Fastest Selector Method in Jquery and CSS - Id or Not

Fastest selector method in jquery and CSS - ID or not?

My testing on modern browsers suggests that you should go with either,

$('#id').find('.class') // or
$('.class')

but not,

$('#id .class')

Reason being that all modern browsers implement getElementsByClassName resulting in almost-constant time lookups by class name (assuming a hash implementation). Which browsers are modern is another subjective question.

Performance of jQuery Selectors with ID

A direct ID selector will always be the fastest.

I've created a simple test case based on your question...

http://jsperf.com/selector-test-id-id-id-id-class

Selecting nested ID's is just wrong, because if an ID is unique (which it should be), then it doesn't matter if it's nested or not.

Is ID selector faster than class selector when it is cached in jquery

You have those stored in variables. So the speed will be the same for both.

The performance hit will occur when you are iterating DOM to get elements. At that time ID selector will be faster than class selector.

In jQuery, is selecting by class or id faster than selecting by some other attribute?

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>

What is faster to find in jQuery - ID's that start with X or a class?

I don't think speed is a concern here, the difference between them is so quick it wont effect your code..

Selector for best performance in jQuery?

If all you want is all instances of DOM elements that match .my-class, then I see no reason why you should use anything other than:

$('.my-class')

The others are all more specific selectors and can be used if you want to narrow the selector to more than just $('.my-class').

If you're really trying to fully optimize performance, than using jQuery in the first place is likely not the desired choice as the overhead of jQuery initialization and jQuery objects tends to slow things down. You use jQuery because it's quick to code and offers great cross-browser support and a bunch of useful methods. You don't use jQuery to optimize performance.

If you really want to compare the performance of your four jQuery options, then you will have to design up a representative set of HTML (which has to include lots of other things to be truly representative of a real world situation) and then test each of your selectors in some benchmarking tool like jsperf and run that test in all browsers that you care about and with the versions of jQuery that you will be using and then see if you can come to some particular conclusion.

This smells like an attempt at premature optimization. Write your code first as simply as possible and only spend time optimizing performance when you've actually measured that you have a performance issue and that this is the place in your code where the performance bottleneck is. 99.99% of the time, the performance of a particular selector is not going to make one iota of difference in your code. Code simply and without complication first. In the 0.01% of the time that you actually want to optimize your code, you will probably care so much about performance that you will either pre-cache the list of elements or you will not code it in jQuery in order to avoid the jQuery object setup and overhead.

Here's a jsPerf: http://jsperf.com/jquery-selector-comparison-specificity/4. This shows relatively little difference between the options when tested in the latest versions of Chrome, Firefox and IE. There is a slight bias in favor of the $('.my-class') option.

And for reference, you will find that:

document.getElementsByClassName("my-class")

is as much as 50x faster than any of the jQuery options.

Here's a screenshot of the jsperf results in Chrome:

Sample Image

Conclusions

  1. For normal coding where you haven't proven you actually have a performance issue that you need to spend time optimizing, use the simplest selector that meets your selection objective.

  2. If it's really performance critical, use plain Javascript, not jQuery.

JQuery class selector vs id selector

You can use an ID filter without multiple selectors:

$('[id^="package"]').click(printPdf);

The above will select all id's starting with "package". This means the difference is mostly semantic. You should choose that which is most meaningful to your application and the way it was developed.

See the jQuery attribute selectors page to learn about the flexibility of jQuery selection. Keeping a bookmark on this page will prevent you from ever having to write code like your second example again.

Which is better?

If you have your structure set up so that you have a class that logically and correctly defines the appropriate set of elements, then that is what you should use to select on.

Likewise, if you have instead given elements specially named IDs and do not have a descriptive class name attached that represents what you want to select, then use the ID selection. The performance difference will be of no concern to almost any application, yours included.

What is the fastest method for selecting descendant elements in jQuery?

Method 1 and method 2 are identical with the only difference is that method 1 needs to parse the scope passed and translate it to a call to $parent.find(".child").show();.

Method 4 and Method 5 both need to parse the selector and then just call: $('#parent').children().filter('.child') and $('#parent').filter('.child') respectively.

So method 3 will always be the fastest because it needs to do the least amount of work and uses the most direct method to get first-level children.

Based on Anurag's revised speed tests here: http://jsfiddle.net/QLV9y/1/

Speed test: (More is Better)

On Chrome, Method 3 is the best then method 1/2 and then 4/5

Sample Image

On Firefox, Method 3 is still best then method 1/2 and then 4/5

Sample Image

On Opera, Method 3 is still best then method 4/5 and then 1/2

Sample Image

On IE 8, while slower overall than other browsers, it still follows the Method 3, 1,2,4,5 ordering.

Sample Image

Overall, method 3 is the overal best method to use as it is called directly and it doesn't need to traverse more than one level of child elements unlike method 1/2 and it doesn't need to be parsed like method 4/5

Though, keep in mind that in some of these we are comparing apples to oranges as Method 5 looks at all children instead of first-level ones.

CSS and jQuery Selector Speed

I'd say that it's extremely unlikely that it makes any real-world difference. In theory, yes, there's one fewer check required (because div#foo really does need to be a div to match the selector, according to the spec). But the odds of it making any real difference in a real-world browser app? Near zero.

That said, I always cringe when I see things like div#foo in HTML applications. HTML has only one ID-type attribute (id), so there's no need for the further qualification. You make the CSS selector engine (either the browser's or jQuery's) work harder to figure out what you mean, you make the selector fragile (if the div becomes a footer, for instance), etc., and of course you do leave yourself open to a stoopid selector implementation that fails to recognize that it can look something up by ID and then check to see if it's a div and so goes looking through all the divs. (Does such an implementation exist? Possibly, you never know.) Barring some edge cases, it always makes me think someone doesn't quite know what they're doing.

So for me, speed isn't the main argument. Pointlessness is. ;-)

jQuery methods Vs jQuery selectors

First of all, yes nikhil was right. ID is unique identifier and can be only used once. If you are willing to apply same styles to several elements, or you to use it to select several elements together use class attribute. But however, i couldn't understand your question. But maybe this could help

there is function in javascript which is widely supported by almost all major browsers

document.querySelectorAll("div [id^=myId]");

in fact you could write your own library (well not as advanced one like jquery but)

var $ = function(selector){
return document.querySelectorAll(selector);
}

// and then you could use it like this
var elementsWithMyId = $("div [id^=myId]");
// where elementsWithMyId will contain array of all divs which's id start with myId

so as i understood your question, No. there is no magic happening behind jQuery selections it's just browser built in function which is kinda shortened by jquery. of course they added tons of new features, which would work like this:

var $ = function(selector){
var elementsArray = document.querySelectorAll(selector);

elementsArray.makeBlue = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "blue";
}
// so elementsArray will now have function to make all of its
// div blues. but if you want to have chain like that, we have to return this array not just make all of it blue
return elementsArray;
}

elementsArray.makeRed = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "red";
}
return elementsArray;
}

return elementsArray;
}

// so now you can use it like this

// this returns array which has options make blue, and make red so lets use make blue first
// makeBlue then returns itself, meaning it returns array which has again options of making itself red and blue so we can use makeRed now
$("div [id^=myId]").makeBlue().makeRed();

and thats it!



Related Topics



Leave a reply



Submit