jQuery Best Practices

Contact Us or call 1-877-932-8228
jQuery Best Practices

jQuery Best Practices

Optimize Selectors

Selector optimization is less important than it used to be, as more browsers implement document.querySelectorAll() and the burden of selection shifts from jQuery to the browser. However, there are still some tips to keep in mind.

ID-Based Selectors

Beginning your selector with an ID is always best. An item preceding an id will actually de-optimize a query, since it will induce jQuery to use getElementsByTagName first, then search by attribute for the id, when the browsers already optimize getElementById.

//Not Optimized
$('ul#myId li');

// Better
$('#myId li');

Design Pages for jQuery Optimization, and Use Your Knowledge of the Page Structure

Adopting and enforcing rules on your HTML code will help create optimized selectors.

  • Use classes to categorize elements.
  • Define and use consistent structures for like elements. For instance, "flyout menus will be implemented as unordered lists, with a specific class for the top level" (and possibly for sublevels as well).
  • Use table section elements, particularly tbody, so that you know that rows will be exactly two levels below the table tag.

A "flatter" DOM also helps improve selector performance, as the selector engine has fewer layers to traverse when looking for an element.

Avoid the Universal Selector

Selections that specify or imply that a match could be found anywhere can be very slow, particularly if the starting point is not very specific.

$('[name=city]');                 // extremely expensive
$('input[name=city]')             // better
$('form input[name=city]');       // even better*
$('#custForm input[name=city]');  // best*

*Note that this assumes that the input is within the form,
 which is no longer required in HTML 5

Use "Safe" Selectors

You should always take care when creating selectors to avoid selecting unwanted elements, particularly when working with nested lists, tables, divs, etc., or when you anticipate that a selector will find only a single tag.

Omitting Nested Elements

One approach is to use the child selector > in your selector:


Another way is to use the children() filter function:


Selecting a Single Element

With an id selector, you can assume that your query will find only a single element. But, with other selectors, that wouldn't necessarily be true. In this case, it doesn't affect your efficiency much to add a :first pseudo-selector to the query. In the example below, perhaps we only want to select one row, and are assuming that the thead section only contains one tr tag:

$('#myTable thead tr')       // would find multiple trs if they existed
$('#myTable thead tr:first') // better

Use Event Delegation

Event delegation allows you to attach an event handler to one container element (for example, an unordered list) instead of multiple contained elements (for example, list items). jQuery makes this easy with $.fn.on. Prior to version 1.7, jQuery used $.fn.delegate for event delegation.

In addition to performance benefits, event delegation also allows you to add new contained elements to your page without having to re-attach the event handlers for them as they're added.

// Bad (if there are lots of list items)

// Best: event delegation
$('#myList').on('click', 'li.trigger', handlerFn);

Detach Elements to Work with Them

The DOM is slow; you want to avoid manipulating it as much as possible. jQuery introduced$.fn.detach in version 1.4 to help address this issue, allowing you to remove an element from the DOM while you work with it.

var $table = $('#myTable');
var $parent = $table.parent();

// add lots and lots of rows to table

Use Stylesheets for Changing CSS on Many Elements

If you're changing the CSS of more than 20 elements using $.fn.css, consider adding a style tag to the page instead for a nearly 60% increase in speed.

// OK for up to 20 elements, slow after that
	$('a.swedberg').css('color', '#abcdef);

	//better if styling many elements
	$('<style type="text/css">a.swedberg { color : #abcdef }</style>')

Note that the above is not an exact replacement -- while the original will result in an inline style, which would override any existing inline style, the alternative presented would not override an existing inline style.

Use $.data Instead of $.fn.data

Using $.data on a DOM element instead of calling $.fn.data on a jQuery selection can be up to 10 times faster. Be sure you understand the difference between a DOM element and a jQuery selection before doing this, though.

// Slower

// Faster

Also, remember that the need for data can be almost completely eliminated by the use of closures, as we have done in most of the demos and exercises.