Unless there is something wrong with my test, when I run this jsfiddle on Chrome I'm getting around 11ms for an $("#id")
selector and 56ms for a $(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;
}
/
Unless there is something wrong with my test, when I run this jsfiddle on Chrome I'm getting around 11ms for an $("#id")
selector and 56ms for a $(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/MhWUc/
Share Improve this question edited Apr 2, 2013 at 17:36 Ian 51k13 gold badges104 silver badges111 bronze badges asked Apr 2, 2013 at 17:18 mazlixmazlix 6,3236 gold badges35 silver badges46 bronze badges 1- In addition to the very good answers below, I would say as you should have unique Id's on a page, there's no point being so specific as div#id... – Laurent S. Commented Apr 2, 2013 at 17:21
4 Answers
Reset to default 11That's because $("#id")
internally uses the native document.getElementById function, which uses a map linking from the id to the (unique) element having this id.
Here's the relevant 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'll notice that :
- it's used when the regex detects the
#someId
form - any provided context only adds a test, and doesn't make it faster
Note that this rule is still true outside of jQuery, when defining CSS rules or using document.querySelector
: when you know the id, there is nothing faster than using document.getElementById
(apart a cached element...).
Been awhile since I've been in the source, but I know that #some-id
selectors used to be handled by document.getElementById()
, whereas more plex ones (e.g., tagName#some-id
) have to go through sizzle and ultimately through document.querySelectorAll
.
$('div#id')
is slower because it doesn't map directly to the native getElementById()
method.
When you use div#id, first all the divs are selected.
When you use #id, it goes directly to the table of ids.