Skip to main content

Comparing the performance of $("#foo .bar”) and $(".bar”, "#foo”)


Scroll down for the getById.getByClassName vs. qSA comparison!





If we wanted to select all elements of class "bar" which are inside the element with the ID "foo" , we could write this:




$( '#foo .bar' )



or this:




$( '.bar', '#foo' )



There are of course other methods to achieve this, but for the sake of this question, let's compare only these two methods.



So, which of the above methods performs better? (Which needs less time to execute?)



I have written this performance test:




(function() {
var i;

console.time('test1');
for( i = 0; i < 100; i++ ) {
$('#question-mini-list .tags');
}
console.timeEnd('test1');

console.time('test2');
for( i = 0; i < 100; i++ ) {
$('.tags', '#question-mini-list');
}
console.timeEnd('test2');
})();



You have to execute it from within the console on the Stack Overflow start-page . My results are:



Firefox:

test1: ~90ms

test2: ~18ms



Chrome:

test1: ~65ms

test2: ~30ms



Opera:

test1: ~50ms

test2: ~100ms



So in Firefox and Chrome, the second method is multiple times faster - just as I expected. However, in Opera the situation is reversed. I wonder what's going on here.



Could you please run the test on your machine and explain why Opera performs differently?





Update



I've written this test, in order to investigate whether Opera's qSA really is super-fast. As it turns out, it is.




(function() {
var i, limit = 5000, test1 = 'test1', test2 = 'test2';

console.time( test1 );
for( i = 0; i < limit; i += 1 ) {
document.getElementById( 'question-mini-list' ).getElementsByClassName( 'tags' );
}
console.timeEnd( test1 );

console.time( test2 );
for( i = 0; i < limit; i += 1 ) {
document.querySelectorAll( '#question-mini-list .tags' );
}
console.timeEnd( test2 );
})();



Again, you have to run this code from within the console on the Stack Overflow start-page. I used the Firebug Lite bookmarklet for IE9 (since that browser doesn't implement console.time ).



So, I compared this method:




document.getelementById( 'A' ).getElementsByClassName( 'B' );



to this method:




document.querySelectorAll( '#A .B' );



I've executed the above script five consecutive times in each browser. The arithmetic means are:



enter image description here



(All numbers are in milliseconds.)



So, the performance of the first method is pretty much the same in the tested browsers (16-36ms). However, while qSA is much slower compared to the first method, in Opera it actually is faster!



So, qSA optimization is possible, I wonder what the other browsers are waiting for...


Source: Tips4allCCNA FINAL EXAM

Comments

  1. jQuery/Sizzle will avoid using the JavaScript based Sizzle engine if the browser supports querySelectorAll, and if you pass a valid selector (no custom, non-CSS selectors).

    This means that you're ultimately comparing implementations of querySelectorAll, assuming you're testing browsers that support it.

    There are other optimizations that jQuery or Sizzle uses, so it's tricky when comparing different types of DOM selection in different browsers.

    The reason for Opera's performance result seems to be that they have a very highly optimized querySelectorAll implementation. qSA, being a relatively new method, hasn't been quite as optimized in some browsers compared to older methods like getElementsByTagName.

    ReplyDelete
  2. For reference, this is 30x faster:

    document.getElementById("foo").getElementsByClassName("bar");


    See jsPerf: http://jsperf.com/jquery-selector-variations/3. This would need a shim to work in older versions of IE.

    While jQuery is extremely useful, if speed is of the utmost, it's not always the best tool for the job.

    ReplyDelete
  3. And the winner is....

    test 3 $('#question-mini-list').find('.tags');


    test1: 25ms
    test2: 19ms
    test3: 10ms


    The two methods you suggested are not equivalent.

    test 1: Sizzle parses from right to left (don't ask it to search ever element on the page, then restrict to an ID).

    test 2: Using a string as a context is generally of no use, use elements as a context.

    test 3: Finding elements with an id is blazingly fast. Once you're there it's a breeze to focus in on an item of a given class.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex