W jQuery, czy wybieranie przez klasę lub id jest szybsze niż wybieranie przez jakiś inny atrybut?

Zasadniczo jest

$("#someid")

Lub

$(".someclass")

Szybciej niż

$("[someattr='value']")

Wyobrażam sobie, że jest (czyli wybór przez id jest najszybszy, potem Klasa, potem atrybut), ale czy ktoś wie na pewno?

Author: Jay, 2011-06-24

6 answers

ID jest absolutnie najszybszy. Jednym z powodów jest to, że ID ma być unikalne, więc API przestaje szukać po znalezieniu ID w DOM.

Jeśli musisz użyć selektora klas lub atrybutów, możesz poprawić wydajność, podając opcjonalny parametr kontekstowy.

Na przykład...

$(".someclass", "#somecontainer")

Gdzie somecontainer jest czymś w rodzaju div, otaczającego element klasą someclass. Może to przynieść ogromne korzyści w przypadku, gdy somecontainer zawiera mały ułamek DOM.


Aktualizacja:

Zrobiłem kilka testów kilka lat temu wokół parametru context. Po przeczytaniu poniższych komentarzy byłem ciekaw, czy coś się zmieniło. Rzeczywiście, wygląda na to, że scena zmieniła się nieco w dzisiejszych przeglądarkach. Może ma to również związek z ulepszeniami w jQuery? Nie wiem.

Oto moje wyniki z 10 000 iteracji (kod jest poniżej):

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

Więc wśród tych dużych 3 nowoczesnych przeglądarek, parametr context tylko wydaje się pomóc IE9. Starsze przeglądarki również skorzystają z parametru context. Ale biorąc pod uwagę powszechność każdej z tych przeglądarek i uśrednianie wszystkiego, zysk netto jest teraz nieco zmyty.

I oto kod na wypadek, gdyby ktoś chciał sam spróbować...

<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>
 71
Author: Steve Wortham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 22:35:24

Wybranie przez ID jest najszybsze, ponieważ mapuje bezpośrednio do getElementByID, pozostałe 2 musi sprawdzić każdy element, aby określić wybrane elementy.

Jeśli musisz wybrać używając klasy lub atrybutu, spróbuj załączyć wyszukiwanie w ID. ex.

$("#someid .someclass")
 11
Author: a programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 21:16:01

ID jest unikalne i jeśli chcesz wybrać tylko jeden / pierwszy element tutaj odpowiednik

$("#someid") = > 75 695 ops/sek, najszybszy

$(.unique_class') = > 45,257 ops/ sek, 40% wolniej : tylko jedna klasa na stronie

$(".someclass").first() => 42,217 ops/sek, 46% wolniej : wiele klas na stronie, select first element

$(".someclass: eq (0)") = > 18,324 ops/sek, 76% wolniej: wiele klas na stronie, wybierz element przy zaznaczonym indeks

Testowy url: http://jsperf.com/jquery-selector-speed-tests/98

 7
Author: ewwink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-20 12:11:52

Selektory ID i klas, przynajmniej gdy są używane przez siebie, wydają się być szybsze, zarówno dla jQuery, jak i dla CSS. Wynika to w dużej mierze z faktu, że przeglądarki mają zoptymalizowane algorytmy dla identyfikatorów i klas w swoich silnikach DOM / CSS.

W nowoczesnych przeglądarkach z najnowszymi wersjami jQuery, wszelkie ciągi selektorów, które są rozumiane jako obsługiwane selektory CSS przez przeglądarkę, będą obsługiwane przez document.querySelectorAll(), oferując maksymalną wydajność tak długo, jak używane są standardowe selektory CSS. Niestandardowe selektory lub starsze przeglądarki są obsługiwane przez jQuery i / lub bibliotekę Sizzle, które dokładają wszelkich starań, aby korzystać z metod get-element(s) DOM do przemierzania DOM.

Najważniejszą rzeczą do zapamiętania jest to, że wydajność będzie się różnić w zależności od przeglądarki (Wersja) do przeglądarki (wersja) z powodu różnych implementacji DOM. Przynajmniej tak mi się wydaje.

 7
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-16 10:32:42

Identyfikator będzie zawsze najszybszy, ponieważ jest unikalny na stronie. Klasa "może" być szybsza niż atrybut, ale to zależy.

Prawdziwym kickerem tutaj jest wybór klasy wewnątrz i ID nie może być szybszy niż tylko wybór klasy. To zależy od strony i przeglądarki. W moich testach wybór złożonej strony z ograniczoną liczbą elementów z "klasą", gdzie rodzic elementu klasy miał id, takie jak:

<div id='iamout'>
  <div class='aonther'>
    <div class='iamin'>stuff</div>
    <div class='iamin'>stuff</div>
  </div>
</div>

Selektor taki jak $('.iamin','#iamout') nie zawsze był tak szybko jak $('.iamin')

Nie wszystkie przeglądarki obsługują select by classname (natywnie), ale nowoczesne/nowsze tak robią, dzięki czemu może oferować lepszą wydajność w zależności od przeglądarki, którą posiadasz.

Jeśli potrzebujesz optymalnej wydajności, musisz przetestować swoją dokładną stronę.

 2
Author: Mark Schultheiss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 21:24:15

Id jest najszybszy, ponieważ jest jedynym elementem, który może mieć ten identyfikator. Wiele obiektów może mieć taką samą nazwę klasy. Ktoś mógłby to zweryfikować, ale wydaje się, że dokument nie musiałby być dalej przesuwany po znalezieniu identyfikatora. W przypadku zajęć może tak nie być?? HTH

 0
Author: webtrifusion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 21:15:18