How to have efficient selectors (Become an expert)
Throughout the book, I've given several hints to improve performances. This recipe will reinforce some of them and add other useful tips and tricks to improve the performance of your website by simply selecting elements in the right way.
How to do it...
To boost the performances, 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 byquerySelectorAll()
. To have better performance, it's better to first select elements using a pure CSS selector and then filter usingfilter()
(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 byquerySelectorAll()
. 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 thenot()
method. For example,turn $('.border [placeholder!=Age]')
into$('.border').not('[placeholder=Age]')
.To improve the performance of
:lt()
filter in modern browsers, use theslice()
method. For example,turn $('.border:lt(2)')
into$('.border').slice(0, 3)
.To improve the performance of the
:gt()
filter in modern browsers, use theslice()
method. For example,turn $('.border:gt(2)')
into$('.border').slice(3)
.To improve the performance of the
:has()
filter in modern browsers, use thehas()
method. For example, turn$('div:has(p.border)')
into$('div').has('p.border')
.