Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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...