Why is $ (div # id) slower than $ (# id)?

If in my test something is wrong when I run this jsfiddle in Chrome, I get about 11ms for the $("#id") selector and 56ms for the $(div#id) selector.

 $(document).ready(function(){ startTime = new Date().getTime(); for (i = 0; i < 10000; i++) { s = $("#idC12"); } $("#idResults").html("c12 by id only time: "+elapsedMilliseconds(startTime)); startTime = new Date().getTime(); for (i = 0; i < 10000; i++) { s = $("div#idC12"); } $("#classResults").html("c12 by tagname#id: "+elapsedMilliseconds(startTime)); }); function elapsedMilliseconds(startTime) { var n = new Date(); var s = n.getTime(); var diff = s - startTime; return diff; } 

http://jsfiddle.net/MhWUc/

+4
source share
4 answers

This is because $("#id") internally uses the built-in document.getElementById function, which uses a map that associates an identifier with a (unique) element that has that identifier.

Here is the corresponding code in jQuery source:

  // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/ ... // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } 

You will notice that:

  • it is used when the regexp detects the form #someId
  • any provided context only adds a test and does not speed up its execution

Note that this rule is still true outside of jQuery when you define CSS rules or use document.querySelector : when you know the identifier, there is nothing faster than using document.getElementById (except for the cached element ...).

+11
source

Some time ago, when I was in the source, but I know that the #some-id selectors were used by document.getElementById() , while the more complex ones (like tagName#some-id ) should go through the hiss and ultimately via document.querySelectorAll .

+2
source

$('div#id') slower because it does not map directly to native getElementById() .

+1
source

When you use div # id, all divs are selected first.

When you use #id, it goes directly to the identifier table.

0
source

All Articles