Before Paul’s talk my understanding of jQuery performance tuning was fairly simplistic:
- Optimize selectors to descend from an id if possible.
- Use tag names when selecting classes and don’t use an excessive number of selectors.
- Define variables instead of selecting the same object repeatedly.
- Optimize your code replacing repetition with object oriented functions.
1. Optimize selectors for Sizzle’s ‘right to left’ model
As of version 1.3, jQuery has been using the Sizzle Javascript Selector Library which works a bit differently from the selector engine used in the past. Namely it uses a ‘right to left’ model rather than a ‘left to right’, which means that given a selector string such as$('div.class span.class2')
the engine starts the search on the right using the most specific selector (the span.class2
) and then checks each ancestor against div.class
rather than starting on the left and checking descendants.But what does that mean for you? Make sure that your right-most selector is really specific and any selectors on the left are more broad. For instance use:
$('.class span.class2')
rather than:$('div.class .class2')
And of course descending from an #id is still always best:$('#id div.class')
2. Use live() not click()
jQuery’s new event handlerlive()
is a much faster alternative to click()
. It comes with an additional benefit that I am extremely excited about: the selector works even with dynamic content, meaning no more reattaching click events every time you change a piece of content.Live is faster and better for all click events and most other jQuery event handling, however stay away from it for tracking onmouseover or onsubmit.
3. Pull elements off of the DOM while you play with them
Let’s say you have a form that you want to append a series of inputs to. Normally you might do this:var theForm = $('#myForm');
inputArr.each(function() {
theForm.append(this);
});
However it’s better to pull the form element off of the DOM while you play around with it:var theForm = $('#myForm');
var formParent = theForm.parent();
theForm.remove();
inputArr.each(function() {
theForm.append(this);
});
formParent.append(theForm);
4. Use find() rather than context
With jQuery selectors, context is good for performance, butfind()
is better. So instead of using context like this:var panels = $('div.panel', $('#content'));
It is better to use find()
:var panels = $('#content').find('div.panel');
More info on context
5. Use HTML 5
HTML 5 means more tags:<section>
, <header>
, <footer>
, etc. More tags mean that there are less items that share a given tag name, which translates into better selector performance.6. Append style tags when styling 15 or more elements
When styling a few elements it is best to simply use jQuery'scss()
method, however when styling 15 or more elements it is more efficient to append a style tag to the DOM:$('<style type="text/css"> div.class { color: red; } </style>')
.appendTo('head');
7. Test selectors using Google Page Speed
The CSS selector optimization rules used by FireBug's Page Speed addon also apply to jQuery. If you want to test how well your selector is optimized, apply it with CSS and see if any selectors are flagged by Page Speed.8. Use object detection even if jQuery doesn't throw an error
It's great that jQuery methods don't throw a ton of errors at your users, but that doesn't mean that as a developer you should just rely on that. Even though it won't throw an error, jQuery will have to execute a number of useless functions before determining that an object doesn't exist. So use a quick object detection before calling any methods on a jQuery object that may or may not exist.9. Use direct functions rather than their convenience counterparts
If you look at the jQuery core you'll notice a variety of functions are just convenience methods for calling other functions, for instance if you callgetJSON()
it calls get()
which calls ajax()
. You can cut this extra work out of the loop by referencing the direct function ajax()
.10. Learn the lesser known methods
With a vast and evolving library like jQuery it can be hard to keep on top of all the methods but it is still very important. Some methods Paul pointed out specifically aremap()
, slice()
, stop()
, queue()
, dequeue()
, prevAll()
, pushStack()
and inArray()
. Learning the variety of methods in your toolkit will help you to better use this library and write more concise code. The worst thing you can do is write a custom function for something that already exists in the jQuery core: besides bloating your Javascript, it would take a lot of effort to write code that is optimized as well as it is by the elite and enormous group of developers who work on and debug the jQuery core.
Source URL: http://jonraasch.com/
0 comments:
Post a Comment