Demystifying the jQuery selectors optimization

April 28th 2009

Lately, I’ve been experimenting a lot with jQuery selectors. I wanted to find the best way to select elements depending on the situations. I’ve found some information online, but most of them didn’t have number and even worst, they were wrong.

So I’ve built a little demo page where you can run the tests yourself, that way you’ll be able to confirm the numbers. Please note that you need a browser that supports script profiling, that can be Firefox with Firebug or Safari/WebKit (those are the one I use). The version of jQuery I used is 1.3. These test are representative of browsers that supports getElementsByClassname (Firefox, Webkit, Opera), the numbers might be off in browsers such as IE6/IE7, lets look at the future, not the past ;)

So to get started, it’s not true that the more precise you are in your selectors, the better. Some people tends to think (I was one of them) that $(’div.element’) was a better selector than only $(’.element’) because you target more preciselly what you are looking for. It’s not true, not only does jQuery execute more calls, but it’s also longer to process. Now lets say you want to be even more precise, not only you know the classname, but you also know this is the first element you’re looking for, your selector would be $(’div.element:first’). It’s even worst than only specifying the type.

graph_1

So unless you really have to be really precise with your selectors, you should use a simple classname selector instead of the other 2.

Now, let’s move to selecting items at a specific position, once again, the simpler the better. Here are the cases I tested : $(’.sample-elements:first’), $(’.sample-elements .last:last’), $(’.sample-elements div.last:last’), $(’.sample-elements div:first’), $(’.sample-elements div:eq(2)’).

graph_21

And I kept the best for the end, ID selector. If you can, this really is the way to go: $(’#second’). Not only is it the faster way to select an element, but it’s also the one that executes the less calls.

graph_3

So that’s it for selectors, but what if you need to use complicated selectors.

What I usually do when I know I’ll have to use the same complicated selector multiple times, I store it in a global variable with a custom namespace. for example, this selector $(’.sample-elements div:eq(2)’) would translate to $third_sample_element. I add a dollar sign before it so I know this is a jQuery object. By doing this, you’ll do the complicated calls once, your object will then be stored in that variable and no more calls will be needed.

This kind of optimization is not “needed” when you develop small apps, but once you go into more compliated stuff, those small changes can really make a difference. And once you know the tricks, it’s really simple to put them into practice

Experimented it yourself? Have your own trick? Share them!

Leave a Reply