Achieving high performance is a huge concern, today more than ever. Every web project should take care of this aspect from the start in order to avoid publishing pages that take up to 10 seconds to load.
Performant code isn’t only something to brag about with friends; it can improve the satisfaction of your users. In this section, you’ll learn some tips and tricks to speed up your code by selecting elements with jQuery the right way.
Avoiding the Universal selector
The first and simplest advice we can give you to improve the performance of a selection is to avoid the Universal selector unless it’s absolutely needed. If in your code you have a selection like
$('form :checkbox');
it’s equivalent to
$('form *:checkbox');
As you might recall, when a selector is omitted in front of a filter, the Universal selector is implicitly assumed. To improve the performance of the previous selection, you should turn it into
$('form input:checkbox');
or even better, recalling what you’ve learned about the context parameter, into
$('input:checkbox', 'form');
This last selection is in most cases faster than the one you saw at the beginning of this section.
Another case where you should avoid the use of the Universal selector is when you’re retrieving all the direct children of a given element. An easy solution to achieve this task that uses the Universal selector is
$('form > *');
But you can do better than that! A better approach is to use the tag name selector and then employ jQuery’s children() function:
$('form').children();
This solution is better because it allows jQuery to call the native JavaScript get-ElementsByTagName() function, which is very fast.
The principle shown in the last example can be applied to other cases. Remember that the best performances are achieved when jQuery can call the JavaScript native functions like getElementById() (the fastest function among similar ones), get-ElementsByTagName(), and so on.
Improving the Class selector
Throughout the app you’ve discovered that, when possible, jQuery uses the JavaScript native functions to speed up the operations performed.
To select elements based on their class name, the library uses the getElementsByClassName() function behind the scenes in browsers that support it: IE9+, Firefox 3+, Chrome, Safari, Opera 9.5+, and many others. In versions of Internet Explorer prior to 9, jQuery is still able to give you the expected result but it has to rely on an implementation of its own. Because of this, if the page contains a huge number of elements, the selection process can be slow.
If you want to improve the performance for Internet Explorer 6–8—for example, if they’re the only browsers you’re targeting (some organizations are really stuck in the past)—you can optimize the search by combining the Class selector with the Element selector. Specifically, you can prepend the latter to the class name of interest.
For example, if you want to select all of the p elements having class description and store them in a variable, you can write
var $elements = $('p.description');
This is a good start to improving the performance of your code, but there’s more that you can do.
Don’t abuse the context parameter
Back in lesson 2 we introduced the second parameter of jQuery() called context. We stated that when using this parameter it’s usually possible to improve the performance of a selection by restricting the latter to one or more subtrees of the DOM, depending on the selector used.
There are cases where the use of context doesn’t improve the performance, though. For example, if you’re selecting an element by its ID, you won’t reap any benefit in specifying context. Even more, in this specific case, you’re worsening the performance. Therefore, avoid writing statements like
var $element = $('#test', 'div');
because it’ll worsen the performance compared to
var $element = $('#test');
The first solution is slower because the library has to retrieve a potentially large number of <div>s first and then test their descendants, instead of immediately taking advantage of the native getElementById() function. In case you wonder how slow it could be, take a look at the astonishing results of the test that are displayed in the chart of figure 15.1.
Figure 15.1. A performance test of a selection of an element using its ID with and without the use of the context parameter (higher is better)

This chart was created using jsPerf, a service that allows you to create and share test cases. It’s a good alternative if you don’t want to run a test on your machine or if you want to share the results.
Thanks to this example, we can extract another good point. In order to allow jQuery to use getElementById(), you should never prepend a tag name to an ID, so avoid writing a selector like $('p#test').
A case where the use of context can often speed up the performance is when you provide an ID. However, this rule isn’t set in stone. In fact, when dealing with performance there isn’t a rule that’s always true or false, and you need to test case by case. Performance depends on a lot of factors such as the number and type of the elements in your page and the browser. The take-away lesson is test, test, and once again, test your selectors to verify what works best in that specific case.
The possible optimizations aren’t over yet. Let’s see what you can do with filters.
Leave a Reply