Julian is one of our SilverStripe developers who works with the rest of the team on large projects, as well as acting as technical lead on projects of his own. He is an American citizen who has never lived in America. He was born and grew up in Germany, studied in the UK, and is now happily living in New Zealand, whose friendly, laid-back culture and natural beauty he values.
This article talks about some of the optimisation techniques I have learnt. Techniques that will hopefully give you significant performance improvements for your own websites.
Your secret weapon to help you battle the monster is this fantastic website: http://jsperf.com
1. Optimise for the slowest browser
Take a look at the above jsperf test.
The “without tag” code runs amazingly fast in Firefox (27,970 operations per second). Does that mean you should take advantage of that and write all your selectors without a tag? No.
Take a look at the data: IE6 runs 9 (nine!) operations per second running the “without tag” code and improves to 554 operations per second when running “with tag”. So, if you have to support IE6, help it along by using using tags and over-specify the jQuery selectors.
The reason iE6 is so slow is that it doesn’t have a built-in getElementByClass function. So, if you use a jQuery selector without a tag the browser has to scan through every single element on the page looking for a match.
2. jQuery Entwine is different
This jsperf test shows that entwine behaves differently in regards to its selectors (it uses a “delegate” binding in the background). So, if you are using Entwine, keep your selectors short and don’t specify the tags.
4. Avoid pseudo class selectors
Pseudo class selectors are very convenient and helpful. However, they are also really slow. Refactor your code to use normal classes instead of relying on pseudo-class selectors and it will run a lot quicker.
5. Chain selectors
I often see code that repeats the same selector multiple times. That is such wasted effort. The browser has to query the DOM three times for the same result. Instead, save the element in a variable. Or, better yet, take advantage of jQuery’s ability to chain method calls.
6. Avoid children() unless you only want children
This is really surprising. If you want to query sub-elements of an element, the “find” method is faster than the “children” method. You might think that because children is more specific, that would be faster. After all, it has less elements to search through. However, that isn’t the case. “Children” first needs to figure out which elements are the direct children of the parent element and that involves a depth-first search of all elements. So, effectively, “children” has to run a “find” first, then filter the results to give you only the direct children. Take home message: always use “find”, unless you specifically want “children”.
7. Use jQuery 1.7 event delegation instead of event binding
jQuery 1.7 has a fantastic new event handler called “on”. If you don’t know about it yet, read about it here: http://api.jquery.com/on/
Traditionally you might have bound an event to multiple DOM elements, but with “on” jQuery encourages you to use event delegation instead. The delegation approach means you only bind to a single element and intercept events as they bubble up the DOM tree. This saves a lot of time and makes the code run much faster.
8. Use window.load when appropriate
9. SilverStripe Requirements combine and minify