Quantcast
Channel: Dumitru Glavan » javascript
Viewing all articles
Browse latest Browse all 10

jQuery Performance Tips Cheat Sheet

$
0
0

I was hunting for jQuery performance tricks for a while to tune my heavy dynamic web app. After digging in a lot of articles decided to make a list of the best common performance tips. I also built a handy jQuery Performance Cheat Sheet that can be printed or placed on my desktop.

Selectors performance tips:

1. Always Descend From an #id

This is the golden rule of the jQuery selectors. The fastest way to select an element in jQuery is by ID:

$('#content').hide();

or select multiple elements descending from an ID:

$('#content p').hide();
2. Use Tags Before Classes

The second fastest selector in jQuery is the Tag selector ($(‘head’)) because it maps to a native JavaScript method, getElementsByTagName(). The best way is to prefix a class with a tag name (and descend from an ID):

var receiveNewsletter = $('#nslForm input.on');

The class selector is among the slowest selectors in jQuery; in IE it loops through the entire DOM. Avoid using it whenever possible. Never prefix an ID with a tag name. For example, this is slow because it will loop through all <div> elements looking for the ‘content’ ID:

var content = $('div#content'); // VERY SLOW, AVOID THIS

Also, DON’T descend from multiple IDs:

var traffic_light = $('#content #traffic_light'); // VERY SLOW, AVOID THIS
3. Use Sub-queries

Cache the parent object then run queries on it:

var header = $('#header');

var menu = header.find('.menu');
// or
var menu = $('.menu', header);

See live example →

4. Optimize selectors for Sizzle’s ‘right to left’ model

As of version 1.3, jQuery has been using the Sizzle Javascript Selector Library which works a bit differently from the selector engine used in the past. Namely it uses a ‘right to left’ model rather than a ‘left to right’. Make sure that your right-most selector is really specific and any selectors on the left are more broad:

var linkContacts = $('.contact-links div.side-wrapper');

instead of:

var linkContacts = $('a.contact-links .side-wrapper');
5. Use find() rather than context

Indeed, the .find() function seems to be faster. But this counts more when you have a lot of traversing a page with lots of DOM elements:

var divs = $('.testdiv', '#pageBody'); // 2353 on Firebug 3.6
var divs = $('#pageBody').find('.testdiv'); // 2324 on Firebug 3.6 - The best time
var divs = $('#pageBody .testdiv'); // 2469 on Firebug 3.6
6. Harness the Power of Chaining

It’s better to chain the jQuery methods than to cache the selectors:

$('li.menu-item').click(function () {alert('test click');})
                     .css('display', 'block')
                     .css('color', 'red')
                     fadeTo(2, 0.7);
7. Write your own selectors

If you have selectors that you use often in your script – extend jQuery object $.expr[':'] and write your own selector. In the next example I create a selector abovethefold that returns a set of elements that are not visible:

$.extend($.expr[':'], {
	abovethefold: function(el) {
		return $(el).offset().top < $(window).scrollTop() + $(window).height();
	}
});
var nonVisibleElements = $('div:abovethefold'); // Select the elements

DOM manipulation performance tips:

8. Cache jQuery Objects

Cache elements that you query often:

var header = $('#header');
var divs = header.find('div');
var forms = header.find('form');
9. Wrap everything in a single element when doing any kind of DOM insertion

DOM manipulation is very slow. Try to modify your HTML structure as little as possible.

var menu = '<ul id="menu">';
for (var i = 1; i < 100; i++) {
    menu += '<li>' + i + '</li>';
}
menu += '</ul>';
$('#header').prepend(menu);

// Instead of doing:

$('#header').prepend('<ul id="menu"></ul>');
for (var i = 1; i < 100; i++) {
    $('#menu').append('<li>' + i + '</li>');
}
10. Use object detection even if jQuery doesn’t throw an error

It’s great that jQuery methods don’t throw a ton of errors at your users, but that doesn’t mean that as a developer you should just rely on that. Even though it won’t throw an error, jQuery will have to execute a number of useless functions before determining that an object doesn’t exist. So use a quick object detection before calling any methods on a jQuery object that may or may not exist.

11. Use direct functions rather than their convenience counterparts

For better performance you can use direct functions like $.ajax() rather than $.get(), $.getJSON(), $.post() because the last ones are shortcuts that call the $.ajax() function.

12. Store jQuery results for later

Usually you have a general javascript application object – App. Keep your often used jQuery selects in it for later:

App.hiddenDivs = $('div.hidden');
// later in your application:
App.hiddenDivs.find('span');
13. Use jQuery’s internal data() method to store state

Don’t forget about using .data() function to store stuff for your elements:

$('#head').data('name', 'value');
// later in your application:
$('#head').data('name');
14. Use jQuery’s utility functions

Don’t forget about jQuery Utilities functions that can be very handy. My favorites are $.isFunction(), $.isArray() and $.each().

15. Add a JS class to your HTML attribute

Firstly, as soon as jQuery has loaded you use it to add a “JS” class to your HTML tag.

$('HTML').addClass('JS');

Because that only happens when javascript is enabled, you can use it to add CSS styles which only work if the user has JavaScript switched on, like this…

/* In your css */
.JS #myDiv{display:none;}

So, what this means is that we can hide content when JavaScript is switched on and then use jQuery to show it when necessary (e.g. by collapsing some panels and expanding them when the user clicks on them), while those with JavaScript off (and search engine spiders) see all of the content, as it’s not hidden. I’ll be using this one a lot in the future.

Read more on this →

Events performance tips:

16. Defer to $(window).load

Sometimes it’s faster to use $(window).load() than $(document).ready() because the last one occurs before all the DOM elements are downloaded. You should test this before you use it.

17. Leverage Event Delegation (a.k.a. Bubbling)

When you have a lot of elements in a container and you want to assign an event to all of them – use delegation to handle it. Delegation provides you with the ability to bind only one event to a parent element and then check on what child the event acted (target). It’s very handy when you have a big table with a lot of data and you want to set events to the TDs. Grab the table, set the delegation event for all the TDs:

$("table").delegate("td", "hover", function(){
	$(this).toggleClass("hover");
});

Read more →

18. Shorthand for the ready event

If you want to save some bits on compressing your js plugin – replace the $(document).onready() event:

// Instead of:
$(document).ready(function (){
    // your code
});

// you can do:

$(function (){
    // your code
});

Testing jQuery:

19. jQuery Unit Testing

The best way to test a Javascript code is the human way :) But, you still can use some automated tools like Selenium, Funcunit, QUnit and QMock to test your code (especially plugins). I will discuss this in another post because there’s a lot to say about it.

20. Benchmark Your jQuery Code

Always benchmark your code and see which query is slower to replace it. You can achieve this with the Firebug console. Also you can use some of my jQuery shortcut functions to make your testing easier:

// Shortcut to log data to the Firebug console
$.l($('div'));

// Get the UNIX timestamp
$.time();

// Log the execution time of a JS block to Firebug
$.lt();
$('div');
$.lt();

// Run a block of code in a for loop to test the execution time
$.bm("var divs = $('.testdiv', '#pageBody');"); // 2353 on Firebug 3.6

General jQuery performance tips:

21. Use latest version of jQuery

The newest version is usually the best one. Also don’t forget to test your code after changing your jQuery core version. Sometimes it’s not fully backward compatible.

22. Use HTML 5

The new HTML 5 standard comes with a lighter DOM structure in mind. Lighter DOM structure means less elements to traverse for jQuery and better load performance. So, switch to it when possible.

23. Append style tags when styling 15 or more elements

When styling a few elements it is best to simply use jQuery’s css() method, however when styling 15 or more elements it is more efficient to append a style tag to the DOM. This way you get rid of hard coding styles in your scripts.

$('<style type="text/css"> div.class { color: red; } </style>')
.appendTo('head');
24. Don’t load code that isn’t needed

It’s a good technique to break your Javascript code in multiple files and load them only on the pages that need them. This way you don’t load unnecessary JS code and selectors. It’s also easy to manage your code this way.

25. Keep download times to a minimum with one compressed master JS file.

After you decide what javascript files you want to load – compress them and glue in one file. This can be done automatically with open source tools like Minify integrated in your backend code or combining them and minifying with online tools like JSCompressor , YUI Compressor or Dean Edwards JS packer. I prefer the JSCompressor from the online tools.

26. Combine jQuery with raw Javascript where needed

It’s a beauty to work with jQuery but don’t forget that it’s just a framework for Javascript. So you can switch between jQuery code and raw Javascript functions where needed to gain more performance.

27. Load the framework from Google Code

Always load jQuery from Google CDN in your production application – it delivers the script fast from the user’s nearest cache location.
This way you save a server request and also the client has the chance to load the jQuery script instantly from his browser cache if he visited another site that loads the jQuery from Google CDN.

// Link the minified version by specific version
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
28. Lazy load content for speed and SEO benefits

Load chunks of your sites by Ajax to save server side loading time. You can start with the usual sidebar widgets.

Special thanks to Paul Irish, Addy Osmani, Jon Hobbs-Smith and Dave Artz for providing lots of information about jQuery performance.

Thanks to @maxescu who designed this beautiful wallpapers!

What other jQuery performance tips do you suggest?

Please support this wonderful wallpapers and

Viewing all articles
Browse latest Browse all 10

Trending Articles