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

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?


Solution 1:

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>

Solution 2:

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")