Archive

Posts Tagged ‘performance’

Efficient jQuery Selectors

March 23rd, 2009 admin Comments off

jQuery is seriously awesome, but if we don’t use it carefully we can put a pretty serious load on the users’ CPU.  This can mean a perceptible delay when the $(document).ready() function runs if there are loads of un-optimized selectors running. Considering that most users spend 4 seconds on a site, 1 or 2 seconds of delay can mean losing your user.  What kinds of jQuery selectors are fastest? Which ones are slower, and which ones must we avoid at all costs to ensure a responsive experience?

Which is fastest?

$(’.box_text’).html(’test1′);
$(’span.box_text’).html(’test2′);
$(’#box_text’).html(’test3′);

Which is fastest? Have a look for yourself on this test page, http://www.ivorycity.com/tests/jquery/selectors/test0.php.

If you’re using FF3, they should all be about the same, but if you’re using IE6,7, or FF2, $(’#box_text’) is up to 10x faster than $(’.box_text’)!

Why is this?

In order to answer these questions, we need to know a little about how jQuery finds DOM nodes.

Internally, jQuery uses document.getElementById() to find elements based on id. Browsers index id’s internally, so the lookup is instantaneous.  Meanwhile,  using $(’.someclass’) in IE causes jQuery to iterate over every element in the DOM to find one with a particular class – that’s crazy slow!

By prefixing ’span’ to the query, we get $(’span.box_text’) – this is a little better because internally, jQuery calls document.getElementsByTagName and iterates the results. Since spans are only a sub-set of all DOM nodes, the query is a lot faster. So if you’re performing lots of ‘naked’ class selectors, you’re going to consume a lot of user cpu.

In Firefox 3 however,  it’s no longer the case that $(’.someclass’) causes an iteration over the DOM; document.getElementsByClassName() was added in FF3 to index element class names inside the browser memory space, which is much, much faster. That’s why we don’t see the same performance hit as in IE.

Now, it may not always be appropriate to access elements by id. If you’re trying to find many instances, say 100+, with a particular class name, it’s actually faster to use $(’.someclass’) than to loop through a set of id’s.

The moral of the story…

1) Use id selectors to reference a ‘needle in a haystack’

2) Use class selectors prudently, and only when referencing large numbers of DOM nodes

3) You can also prevent iteration over the entire dom by doing something like $(’#myid .myclass’) which only searches sub-nodes of #myid.

Categories: jQuery Tags: ,