web-dev-qa-db-fra.com

Dans jQuery, la sélection par classe ou par ID est-elle plus rapide que par un autre attribut?

Fondamentalement, est 

$("#someid")

ou

$(".someclass")

plus rapide que

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

J'imagine que c'est le cas (c'est-à-dire que la sélection par identifiant est la plus rapide, puis la classe, puis l'attribut), mais est-ce que quelqu'un le sait?

42
Jay

ID est absolument le plus rapide. Une partie de la raison est que l'ID est censé être unique, aussi l'API cesse-t-elle de chercher après que l'ID ait été trouvé dans le DOM.

Si vous devez utiliser un sélecteur de classe ou d'attribut, vous pouvez améliorer les performances en spécifiant le paramètre contextuel facultatif.

Par exemple...

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

somecontainer est quelque chose comme une div, entourant un élément avec la classe someclass. Cela peut offrir un avantage considérable en termes de performances dans les cas où somecontainer ne représente qu'une petite fraction du DOM. 


METTRE À JOUR:

J'ai fait des tests il y a quelques années autour du paramètre context. Après avoir lu les commentaires ci-dessous, j'étais curieux de savoir si quelque chose avait changé. En effet, il semble que la scène ait quelque peu changé avec les navigateurs actuels. Peut-être que cela a également à voir avec les améliorations de jQuery? Je ne sais pas.

Voici mes résultats avec 10 000 itérations (le code est ci-dessous):

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

Donc, parmi ces 3 grands navigateurs modernes, le paramètre context semble seulement aider IE9. Les anciens navigateurs bénéficieront également du paramètre context. Mais compte tenu de la prévalence de chacun de ces navigateurs et de la moyenne de tous, le gain net est un peu un lavage maintenant.

Et voici le code au cas où quelqu'un voudrait l'essayer lui-même ...

<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
Steve Wortham

La sélection par ID est la plus rapide, car elle mappe directement à getElementByID, les 2 autres doivent vérifier chaque élément pour déterminer les éléments sélectionnés.

Si vous devez sélectionner en utilisant classe ou attribut, essayez de placer la recherche dans un ID . Ex.

$("#someid .someclass")
11
a programmer

L'ID est unique et si vous ne voulez sélectionner qu'un seul/premier élément ici, l'équivalent 

$ ("# someid") => 75 695 ops/sec, le plus rapide

$ (. unique_class ') => 45 257 ops/s, 40% plus lent: une seule classe sur la page

$ (". someclass"). first () => 42 217 ops/s, 46% plus lent: plusieurs classes sur la page, sélection du premier élément

$ (". someclass: eq (0)") => 18 324 ops/s, 76% plus lent: plusieurs classes à la page, élément sélectionné à l'index sélectionné

URL de test: http://jsperf.com/jquery-selector-speed-tests/98

7
ewwink

Les sélecteurs d'ID et de classe, du moins lorsqu'ils sont utilisés seuls, ont tendance à être plus rapides, que ce soit pour jQuery ou pour CSS. Cela est dû en grande partie au fait que les navigateurs ont optimisé les algorithmes pour les ID et les classes dans leurs moteurs DOM/CSS.

Dans les navigateurs modernes dotés de versions récentes de jQuery, toutes les chaînes de sélecteurs comprises comme des sélecteurs CSS pris en charge par un navigateur sont gérées par document.querySelectorAll(), offrant ainsi des performances maximales tant que les sélecteurs CSS standard sont utilisés. JQuery et/ou la bibliothèque Sizzle prennent en charge les sélecteurs non standard ou les anciens navigateurs, qui font de leur mieux pour utiliser les méthodes get-element (s) du DOM pour parcourir le DOM.

La chose la plus importante à garder à l'esprit est que les performances varient d'un navigateur (version) à l'autre (version) en raison de la diversité des implémentations DOM. Au moins, c'est comme ça que je pense.

7
BoltClock

L'identifiant sera toujours le plus rapide puisqu'il est unique sur la page. La classe "peut" être plus rapide qu'un attribut mais cela dépend.

Le véritable facteur déterminant ici est la sélection d’une classe au sein de laquelle l’ID n’est PAS plus rapide que la sélection de la classe. Cela dépendra de la page et du navigateur. Lors de mes tests, sélection d'une page complexe avec un nombre limité d'éléments avec une "classe" où le parent de l'élément de classe avait un identifiant tel que:

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

un sélecteur tel que $('.iamin','#iamout') n'était pas toujours aussi rapide que $('.iamin')

Tous les navigateurs ne prennent pas en charge la sélection par nom de classe (en mode natif), contrairement aux navigateurs modernes ou plus récents, qui peuvent donc offrir de meilleures performances en fonction du navigateur utilisé.

Si vous souhaitez obtenir des performances optimales, vous devez tester votre page exacte.

2
Mark Schultheiss

Id est le plus rapide, car c'est le seul élément pouvant avoir cet identifiant. De nombreux objets peuvent éventuellement avoir le même nom de classe. Quelqu'un pourrait le vérifier, mais il semblerait que le document n'aurait plus besoin d'être parcouru une fois l'identifiant trouvé. Pour les cours, cela peut ne pas être le cas ?? HTH

0
webtrifusion