Selector Efficiency
A couple of recent illuminations regarding jQuery code that I am putting up here, for my review, and general share.
This information came from a jQuery meetup in LA and a presentation by Christian Ziebarth
To boost performance, keep in mind the following points:
- Don’t use the Universal selector (explicitly or implicitly). Never! Seriously!
- The best selectors are the Id, Class and Element selectors, because under the hood jQuery uses native JavaScript functions.
- The best performances are achieved using the ID selector.
- Never prepend a tag name before an id, it’ll slow down the selector. For example, don’t turn $(‘#content’) into $(‘div#content’).
- If your selection needs more than one selector, start with the Id selector if possible. For example, $(‘#content p.border’).
- Remember to use the context parameter or the find() method when possible. For example, turn $(‘#content p.border’) into $(‘p.border’, ‘#content’) or equivalently (as discussed in the Context Matters should know recipe) into $(‘#content’).find(‘p.border’).
- jQuery’s selectors engine, called Sizzle, parses selectors from right to left. Therefore, to speed up your selection, be more specific on the right part and less on the left. For example, turn $(‘div.wrapper .border’) into $(‘.wrapper p.border’).
- Don’t be too specific if the same set can be selected with less selectors. For example, $(‘#content p.border’) is better than $(‘#content div.wrapper div p.border’).
- If you need to use a filter, it’s always better to narrow down the set of elements and then use the filter. For example, turn $(‘:enabled’) into $(‘#formId’). find(‘:enabled’) or even better $(‘#formId’).find(‘input:enabled’).
- Filters such as, :button, :checkbox, :visible, :input, and others are a jQuery extension and not part of the CSS specification, so they can’t take advantage of the performance provided by querySelectorAll(). To have better performance, it’s better to first select elements using a pure CSS selector and then filter using filter() (that is,.filter(‘:input’)).
- Filters such as, :image, :text, :password, :reset and others are a jQuery extension and not part of the CSS specification, so they can’t take advantage of the performance provided by querySelectorAll(). To have better performance, it’s better to select using the attribute selector. For example, turn $(‘:reset’) into $(‘[type=reset]’).
- To improve the performance of the Not Equal attribute selector in browsers that support querySelectorAll(), use the not() method. For example, turn $(‘.border [placeholder!=Age]’) into $(‘.border’). not(‘[placeholder=Age]’).
- To improve the performance of :lt() filter in modern browsers, use the slice() method. For example, turn $(‘.border:lt(2)’) into $(‘.border’). slice(0, 3).
- To improve the performance of the :gt() filter in modern browsers, use the slice() method. For example, turn $(‘.border:gt(2)’) into $(‘. border’).slice(3).
- To improve the performance of the :has() filter in modern browsers, use the has() method. For example, turn $(‘div:has(p.border)’) into $(‘div’). has(‘p.border’).
Writing Better jQuery Code
This information came from Mathew Carella article at flippin’ awesome, read the entire article it is very thorough.
Avoid Globals With jQuery, as with JavaScript in general, it is best to ensure that your variables are properly scoped within your functions.
// bad
$element = $('#element');
h = $element.height();
$element.css('height',h-20);
// good
var $element = $('#element');
var h = $element.height();
$element.css('height',h-20);
You must log in to post a comment.