In a recent post, I wrote that developers should better optimize their JavaScript. Well, that’s easier said than done, so I’d like to get down to the nitty-gritty and talk specifically about optimizing jQuery. Please note that this is not about performance tuning of the jQuery library, rather it is about better engineering the code we use to interact with it. If you’re not a jQuery programmer, and you have no interest in joining the fad, don’t worry—most of the concepts here apply to JavaScript and general programming as well.
1. Beware of class-only selectors
A great part about using a JavaScript library like jQuery is its selectors. But before you use them all over the place, stop to think: what are the processing costs?
Basically, jQuery defines all the elements on a page as a huge JavaScript object, and then interacts with it. You don’t have to look into the source code to realize that the selector function works by iterating all objects that fit a certain criteria. Therefore, it makes sense to give the selection function a helping hand by defining the selection criteria more specifically.
Let’s do a quick case-study:
Pretend you’re doing site navigation and want to select an LI that has the CSS class ‘active.’ One way to select this element is:
$('.active')
This selector works just fine, but think about what the jQuery DOM traversal has to do here: iterating through hundreds of elements on the page, selecting any with the class ‘active.’ That’s a lot of processing for our little nav bar.
It turns out, according to selector speed tests, that a CSS class alone is just about the worst way to select an object, since jQuery must go through literally every element on the page. Instead, narrow it down a bit using the element that the class is attached to:
$('LI.active')
With only a couple LI’s on the page, this selector performs much better—in half the time on my FF3 and Safari.
2. Select top level by id
That last object selection could be further optimized by using an id in addition to the element and class. As explained in this jQuery performance tip, jQuery’s DOM traversal processes id selection fastest, followed by element and class selection. So it is better to select the list element using:
$('#menu LI.active')
Interestingly, here it is less efficient to use $(‘UL#menu LI.active’), since adding the UL element at the head of the selector causes jQuery to use the worse selection method. Stick with $(‘#menu LI.active’) and remember that the top level node is the most important to select efficiently.
3. Define objects when using selectors
We’ve already established that the selector function is pretty resource heavy, so let’s think of some ways to avoid using it if possible. Mainly, let’s never select the same thing more than once through the jQuery DOM traversal. In our example, we can define an object:
$active = $('#menu LI.active');
Now we are free to use this element as much as we want without worrying about traversal processing.
4. Avoid doing anything you don’t have to1
It may seem like common sense, but it is important to avoid executing extraneous functions.
Suppose that in parts of a site we want to collapse side navigation elements on page load:
$(document).ready(function() {
$('#sideNav LI:not(#current)').hide();
});
Even though some pages don’t have the side nav, this won’t throw an error in any browser, but let’s still make sure that the hide function only executes when it’s needed:
$(document).ready(function() {
var sideNavPages = ['catalog', 'order', 'contact'];
if ( jQuery.inArray(thisPage, sideNavPages) != -1 ) {
$('#sideNav LI:not(#current)').hide();
}
});
I think there is a real tendency with jQuery to execute way more code than is neccessary for a page, since jQuery won’t error the way JavaScript will if you are trying to select an object that does not exist. But we have to be responsible as developers: even if the client can’t see a blatant error warning, you’ll still know you wrote horrible code.
5. Learn the library completely
Some developers who got into jQuery early are missing out on a lot of the functions released with later versions. Sure they use the latest version when they build a new site, but they interface with it in an old way. After reading an old tutorial, I was using:
a.hasClass('b') ? a.removeClass('b') : a.addClass('b');
instead of:
a.toggleClass('b');
Presumably the developers engineering the jQuery library spent more time on optimization than you have on any individual front-end. So read the docs and use the native jQuery functions since they’ll run faster than any self-written function. At the very least, they’ll contribute to the conciseness and readability of the code.
1This rule applies to jQuery, JavaScript, computer programming, and life in general
Nice tips. #5 is definitely the most difficult. I have been using jQuery since the early days and yet I still find things in the library to take advantage of!
Really awesome tutorial…. I have used the fadeIn and fadeOut options of jquery but only once am able to use it in the second time I dnt see any effects, please can u clarify…
Thanks for nice tricks.
Great read! Thanks for sharing. With every new selector/filter or trick, jQuery is making more sense and fun. 🙂
Cool. I enjoyed reading it. I believe the 5th tip is obvious and i am one among those guys who haven’t learnt the library completely (having used jQuery for two years). Great post 🙂
I was specifically wondering about selection speed, and tips 1 – 3 answer my questions to a “T”. THANKS!!!
thanks ,that was great.is there any solution for paging data in jquery?
thanks for sharing this tips,:)
Hello Jon,
The tricks you have suggested are just amazing.
I appreciate your talent.
Thanks and regards,
Amol A. Bhavsar
Another note about performance… you can pass a scope into the selector…. Both of these sections of code do the same thing, one just uses a node reference to define the scope instead of redefining the ID value forcing a full select again.
$(‘#widget1 div.banner:last’)
——————————————————–
el = $(‘#widget1’);
$(‘div.banner:last’, el)
Thanks for the insights!
thanx it was very useful..
With all the doggone snow we have had as recently I am bound inside , fortunately there is the net, cheers for leaving me something to do
Always try to use valid CSS selectors while querying jQuery. Because jQuery uses in-built and powerful querySelectorAll() method to traverse DOM. And if we use selectors like $(‘:hidden’), here :hidden is not a valid CSS rule, then jQuery will not use querySelectorAll() and instead it will so the linear search over the DOM which is slow.