jQuery Selectors, efficiency
Asked Answered
P

6

11

I have been reading more lately about the efficiency of the different selector engines. I know that jQuery uses the Sizzle engine and this blog post about some jQuery stuff mentioned that the Sizzle engine will break apart your selector into an array then parse left to right.

It then, from right to left, begins deciphering each item with regular expressions. What this also means is that the right-most part of your selector should be as specific as possible — for instance, an id or tag name.

My question is whether it is more efficient to run a selector with just the ID specified or the tag name as well:

var div = $('#someId');
//OR
var div = $('div#someId');

Since I write my CSS in the div#someId form I tend to do my selectors the same way, am I causing Sizzle to perform extra work (assuming QuerySelectorAll is unavailable)?

Pang answered 31/8, 2011 at 19:8 Comment(2)
Great question! I was thinking about asking a similar question myself.Obscure
For performance questions the best answer is usually to try it yourself. jsperf.com can help you benchmarking javascript snippets.Barolet
P
15

jQuery and Sizzle optimize the #id selector [source] to document.getElementById(id). I think they aren't able to optimize it like this with the tag#id.

The first is faster.

BTW specifying the tag name for an #id selector is over-specifying, as there can be only one tag with a given id on the document. Over-specifying is slower even in CSS.

Polyester answered 31/8, 2011 at 19:11 Comment(1)
Thanks your response and @lonesomeday's jsPerf answered my question fully. Apparently I need to change my development stylePang
M
8

Rather than speculating, let's measure it!

Here's a test case with this page loaded, then matching a random element with both methods.

Make sure you scroll right down to the bottom.

http://jsperf.com/which-jquery-sizzle-selector-is-faster#runner

As you might expect, a plain id is faster than a tag qualified one (reduction to getElementByID). This is the same when using classes.

Selecting by ID is massively faster than selecting by class, mainly as IDs are guaranteed to be unique.

Millennial answered 31/8, 2011 at 19:20 Comment(0)
P
4

If you are using jQuery, you can assume a browser with getElementById. $('#someId') can be converted to document.getElementById('someId'). $('div#someId') won't be, so it will be faster to lose the tag name.

jsPerf demonstrating this. The difference is enormous.

Penology answered 31/8, 2011 at 19:11 Comment(1)
Amazing, the difference in speed here was astonishing. I will have to evaluate how I do my selectors. I was under the impression that it was smart enough to convert $('div#someID') to getElementById('someID') but it makes sense that I'm adding another constraint in my selector, it has to be a div. Thanks for this.Pang
L
1
var div = $('#someId'); //should be faster

jQuery will use getElementById() for the above selector

var div = $('div#someId'); //would probably preform slower due to finding all the divs first

jQuery will use getElementsByTagName(), then iterate though the array of elements for the above selector

You should also remember, tag names should definately be used with class selectors (whenever possible)

var div = $('div.myclass') //faster than the statement below

versus

var div = $('.myclass') //slower
Lonlona answered 31/8, 2011 at 19:11 Comment(2)
Why ? (Given that browser have document.getElementsByClassName now ?)Polyester
@arnaud576875 getElementsByClassName is not available in all browsers. It will make use of it if it is available but older browsers do not support the function. Such as IE 7Lonlona
P
0

JsPerf: http://jsperf.com/jquery-id-vs-tagname-id

The first one is going to be faster because it only has to check the id. The second one runs the same check AND has to make sure the tagname is correct. div#id won't give you the element with id id unless it is a div

Perlaperle answered 31/8, 2011 at 19:14 Comment(0)
O
0

You can see from the source code here: http://code.jquery.com/jquery-1.6.2.js in the function init.

The fastest selector is $('') which just returns an empty jQuery object immediately.

$('body') is next, which jQuery converts to document.body

The next is $('#id') which uses document.getElementById('id').

Any other selector such as $('div#id') will just become a call to $(document).find('div#id'). find() is very complex compared to any of those other solutions and uses Sizzle JS to select the div.

Oribel answered 31/8, 2011 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.