It was recently pointed out to me that the results of the blog post on jQuery Selector Performance that I wrote in 2011 may be out of date. I think we can all agree that if you’re looking for answers about almost anything web related, it’s probably a good idea to take any three-year-old answers with a grain of salt. But the comment got me thinking, so I went back to take a look at the tests and do some more research.
Updated Test
The first thing that I noticed was that the version of jQuery that I used for the original blog post was 1.4.2. I set to creating a new test with a modern version of jQuery (1.11.1) to see what kind of results I would get. When I did this, another thing struck me as odd.
$(‘.container .main ul.list-1 li’)
$(‘.container’).find(‘.main’).find(‘ul.list-1′).find(‘li’)
$(‘.container’).children(‘.main’).children(‘ul.list-1′).children(‘li’)
$(‘.container’).children(‘.main’).children(‘ul.list-1′).children(‘.odd’)
$(‘.container .main ul.list-1 li.odd’)
These are horrible selectors! Shame on you, 2011 Rob Tarr. Shame.
Test Results
After looking at the results more closely, it seems that it’s not even about whether you chain the query or use jQuery’s children or find methods. The first two: $(‘.container .main ul.list-1 li’)
and $(‘.container’).find(‘.main’).find(‘ul.list-1′).find(‘li’)
ran in almost the exact time. $(‘.container’).children(‘.main’).children(‘ul.list-1′).children(‘.odd’)
came out near the top, but nothing came close to $(‘.container .main ul.list-1 li.odd’)
.
The clear winner here? None of them.
First of all, if your selectors look like .container .main ul.list-1 li.odd
, they’re hard to read. Secondly, they’re probably redundant. How many other things on the page have the .odd
class? Could you simply use .odd
and get the elements that you need?
It seems to me that the real win here comes from writing good markup with class names that clearly identify what you need to hook into with your JavaScript. Perhaps something along the lines of .js-these-are-the-items-i-want
is better suited for your needs.
TL;DR
The big take away here is that shorter, more descriptive class names are more efficient. $(‘.js-these-are-the-items-i-want’)
is better than $(‘.odd’)
, and $(‘.odd’)
is way better than $(‘.container .main ul.list-1 li.odd’)
.