Reputation: 3531
Basically, is
$("#someid")
or
$(".someclass")
faster than
$("[someattr='value']")
I would imagine that it is (that is, selection by id is fastest, then class, then attribute), but does anyone know for sure?
Upvotes: 46
Views: 38622
Reputation: 723548
ID and class selectors, at least when used by themselves, tend to be faster, whether for jQuery or for CSS. This is due largely to the fact that browsers have optimized algorithms for IDs and classes in their DOM/CSS engines.
In modern browsers with recent versions of jQuery, any selector strings that are understood as supported CSS selectors by a browser will be handled by document.querySelectorAll()
, offering maximum performance as long as standard CSS selectors are used. Non-standard selectors or older browsers are taken care of by jQuery and/or the Sizzle library, which do their best to make use of the DOM's get-element(s) methods to traverse the DOM.
The most important thing to remember is that performance will vary from browser (version) to browser (version) because of differing DOM implementations. At least, that's how I believe things are.
Upvotes: 7
Reputation: 19154
ID is unique and if you only want to select one/first element here the equivalent
$("#someid") => 75,695 ops/sec, fastest
$(.unique_class') => 45,257 ops/sec, 40% slower : only one class on page
$(".someclass").first() => 42,217 ops/sec, 46% slower : multiple class on page, select first element
$(".someclass:eq(0)") => 18,324 ops/sec, 76% slower : multiple class on page, select element at selected index
Test url: http://jsperf.com/jquery-selector-speed-tests/98
Upvotes: 7
Reputation: 22220
ID is absolutely the fastest. Part of the reason is that ID is supposed to be unique, so the API stops searching after the ID is found in the DOM.
If you must use a class or attribute selector, you can improve performance by specifying the optional context parameter.
For example...
$(".someclass", "#somecontainer")
Where somecontainer
is something like a div, surrounding an element with class someclass
. This can offer a huge performance benefit in the cases where somecontainer
comprises a small fraction of the DOM.
UPDATE:
I did some tests a couple years ago around the context parameter. After reading the comments below I was curious if anything has changed. Indeed, it seems the scene has changed somewhat with today's browsers. Maybe it also has to do with improvements in jQuery? I don't know.
Here are my results with 10,000 iterations (code is below):
IE9
$(".someclass")
- 2793 ms
$(".someclass", "#somecontainer")
- 1481 ms
Chrome 12
$(".someclass")
- 75 ms
$(".someclass", "#somecontainer")
- 104 ms
Firefox 3.6
$(".someclass")
- 308 ms
$(".someclass", "#somecontainer")
- 357 ms
So among these big 3 modern browsers, the context parameter only seems to help IE9. Older browsers will also benefit from the context parameter. But considering the prevalence of each of these browsers and averaging everything out, the net gain is somewhat of a wash now.
And here's the code in case anyone wants to try it themselves...
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
startTime = new Date().getTime();
for (i = 0; i < 10000; i++)
{
s = $(".someclass");
}
$("#withoutcontext").html(elapsedMilliseconds(startTime));
startTime = new Date().getTime();
for (i = 0; i < 10000; i++)
{
s = $(".someclass", "#somecontainer");
}
$("#withcontext").html(elapsedMilliseconds(startTime));
});
function elapsedMilliseconds(startTime)
{
var n = new Date();
var s = n.getTime();
var diff = s - startTime;
return diff;
}
</script>
</head>
<body>
<h1>jQuery Selector Performance: Context vs No Context</h1>
<h2>$(".someclass")</h2>
<span id="withoutcontext">---</span> ms<br /><br />
<h2>$(".someclass", "#somecontainer")</h2>
<span id="withcontext">---</span> ms<br /><br />
<hr />
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<div id="somecontainer">
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="someclass">someclass</p>
</div>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
<p class="a">a</p>
<p class="b">b</p>
<p class="c">c</p>
</body>
</html>
Upvotes: 71
Reputation: 34168
The id will always be fastest as it it unique on the page. The class "may" be faster than an attribute but it depends.
The real kicker here is selection of a class within and ID may NOT be faster than just selection of the class. It will depend on the page and browser. In my testing, selection of a complex page with a limited number of elements with a "class" where the parent of the class element had an id such as:
<div id='iamout'>
<div class='aonther'>
<div class='iamin'>stuff</div>
<div class='iamin'>stuff</div>
</div>
</div>
a selector such as $('.iamin','#iamout')
was not always as fast as $('.iamin')
Not all browsers support select by classname (natively), but modern/newer ones do and thus it might offer better performance depending upon which browser you have.
If you need to have optimum performance you will need to test your exact page.
Upvotes: 2
Reputation: 959
Selecting by ID is the fastest, because it maps directly to getElementByID, the other 2 has to check each element to determine the selected elements.
If you must select using class or attribute, then try enclosing the search in a ID. ex.
$("#someid .someclass")
Upvotes: 11
Reputation: 4556
Id is fastest, because it is the only element that can have that identifier. Many objects could possibly have the same class name. Someone could verify this, but it would seem like the document would not need to be traversed any further once the id was found. For classes this may not be the case?? HTH
Upvotes: 0