Tips for making jQuery selectors faster - Byron Salau

Posted by | September 19, 2011 | javascript | No Comments

Unfortunately jQuery selectors aren’t stupid proof. Its all too easy to chuck a long string of junk into your selector and not have a single problem. You might have the attitude of, “meh it works” and not give it any more thought of if there is a better way.

The upside of actually paying attention to your jQuery selectors is: the faster they execute the faster your page is going to render and operate. This is especially true for browsers with slower javascript engines like Internet Explorer and phones/devices with lower memory.

I hope that you find using my following tips your jQuery selectors will become optimized to the fastest execution time humanly possible.

Let me introduce you to “Sizzle”

Sizzle is the selector engine jQuery uses and was created by John Resig and the jQuery team. To begin writing optimal selectors you need to first understand how Sizzle works. Given this selector $(‘.content .foo .bar’). Have a minute to think about how you would actually go about finding all the bar elements that are a child of foo and that is a child of content if you were to code a selector engine yourself.

Sizzle’s solution is by reading selectors back-to-front. So looking at the selector again $(‘.content .foo .bar’) you need think right to left. It will find all of the bar elements, then with the results find all the ones with a parent of foo. With those results it will find all the ones with the parent content. This may seem strange but its actually the fastest way to filter the DOM for your desired element(s).

If you now understand how sizzle works we can start optimizing what we tell it to look for. So perhaps in the DOM all we needed to look for was $(‘.foo .bar’) and this would execute faster.

Its all about the context

When you pass a string into a jquery selector the constructor method tries to figure out what you passed in. When context is a DOM element jquery will transform $(selector, context) into $(context).find(selector).

In this case, you can give jquery a helping hand by calling that method your self and avoid all the logic the constructor would have to do to figure it out.

Its a good idea to keep selector strings to the bare minimal so we are not asking the constructor to do time consuming logic.

Harness the power of the ID

Sizzle has been optimized for selecting ID elements with the native javascript function. getElementById() which is the fastest native way of selecting DOM elements.

Always use id’s as your first preference.

Tag before Class

The second fastest selector is selecting elements by their tag. eg $(‘div’)
The slowest is selecting elements by class name eg $(‘.foo’)

With this knowledge tags should definitely be used with classes where possible.


$('div.foo') //faster
$('.foo') //slower

Study the scheme of your elements

Using the correct jQuery methods with our selectors is a very powerful way of speeding up execution time. For example lets have a look at this html snippit from a page and a few ways you can write a selector for the list(<li>) items in the list.


<ul id="foo">
	<li><a href="#">my link</a></li>
</ul>

We could select bar in the following ways:

$(‘li’)
$(‘#foo li’)
$(‘#foo’).find(‘li’)
$(‘#foo’).children(‘li’)

So lets think about which one will execute the fastest. You should be able to do this without the need for bench marking simply by stopping and thinking about the logic jQuery will need to do for each one.

The first one is asking jQuery to traverse through every single DOM element in the page. This is badly expensive.
The second one is better, we are specifying an id at least however sizzle’s constructor logic is going to transform that into something that looks similar to number 3 anyway.
So number three is looking good yes? Well, we are only interested in the <li> element(s) and find() is going to look into into the <a> elements as well looking for any more <li>’s that we can clearly see aren’t there.
Number four is only going to traverse the immediate children of #foo and is absolutely the fastest selector out of these options. Give your self a pat on the back if this is the one you chose.