web-dev-qa-db-fra.com

Quelle est la méthode la plus rapide pour sélectionner des éléments descendants dans jQuery?

Autant que je sache, il existe un certain nombre de façons de sélectionner des éléments enfants dans jQuery .

//Store parent in a variable  
var $parent = $("#parent");

Méthode 1 (en utilisant une étendue)

$(".child", $parent).show();

Méthode 2 (la méthode find ())

$parent.find(".child").show();

Méthode 3 (pour les enfants immédiats uniquement)

$parent.children(".child").show();

Méthode 4 (via le sélecteur CSS) - suggéré par @spinon

$("#parent > .child").show();

Méthode 5 (identique à Méthode 2 ) - selon @Kai

$("#parent .child").show();

Je ne suis pas familier avec le profilage pour pouvoir enquêter par moi-même, donc j'aimerais voir ce que vous avez à dire.

P.S. Je comprends qu'il s'agit d'un doublon possible de cette question mais il ne couvre pas toutes les méthodes.

101
Marko

Méthode 1 et méthode 2 sont identiques, la seule différence étant que la méthode 1 doit analyser la portée passée et la traduire en un appel à $parent.find(".child").show();.

Méthode 4 et Méthode 5 les deux doivent analyser le sélecteur, puis juste appeler: $('#parent').children().filter('.child') et $('#parent').filter('.child') respectivement.

Donc la méthode 3 sera toujours la plus rapide car elle doit faire le moins de travail et utilise la méthode la plus directe pour obtenir des enfants de premier niveau.

Basé sur les tests de vitesse révisés d'Anurag ici: http://jsfiddle.net/QLV9y/1/

Test de vitesse: (Plus c'est mieux)

Sur Chrome , la méthode 3 est la meilleure puis la méthode 1/2 puis 4/5

enter image description here

Sur Firefox , la méthode 3 est toujours meilleure que la méthode 1/2 puis 4/5

enter image description here

Sur Opera , la méthode 3 est toujours meilleure que la méthode 4/5 puis 1/2

enter image description here

Sur IE 8 , bien que globalement plus lent que les autres navigateurs, il suit toujours la méthode 3, 1,2,4,5.

enter image description here

Dans l'ensemble, la méthode 3 est la meilleure méthode globale à utiliser car elle est appelée directement et elle n'a pas besoin de traverser plus d'un niveau d'éléments enfants contrairement à méthode 1/2 et il n'a pas besoin d'être analysé comme la méthode 4/5

Cependant, gardez à l'esprit que dans certains d'entre eux, nous comparons des pommes à des oranges car la méthode 5 examine tous les enfants au lieu de ceux du premier niveau.

95
Aaron Harun

Méthode 1

Ne peut pas être plus court et plus rapide en utilisant jQuery. Cet appel descend directement à $(context).find(selector) (méthode 2, en raison de l'optimisation) qui à son tour, appelle getElementById.

Méthode 2

Fait la même chose, mais sans certains appels de fonction internes inutiles.

Méthode

utiliser children() est plus rapide que d'utiliser find(), mais bien sûr, children() ne trouvera que les enfants directs de l'élément racine tandis que find() recherchera récursivement de haut en bas à tous les enfants elemens (y compris les sous-éléments enfants)

Méthode 4

L'utilisation de sélecteurs comme celui-ci doit être plus lente. Étant donné que sizzle (qui est le moteur de sélection de jQuery) fonctionne de droite à gauche, il correspondra à TOUTES les classes .child Avant de chercher s'il s'agit d'un enfant direct de id 'parent'.

Méthode 5

Comme vous l'avez dit correctement, cet appel créera également un appel $(context).find(selector), en raison d'une optimisation au sein de la fonction jQuery, sinon il pourrait également passer par le (plus lent) sizzle engine .

13
jAndy

Comme c'est un vieux poste, et les choses changent avec le temps. J'ai fait quelques tests sur les dernières versions du navigateur jusqu'à présent, et je le poste ici pour éviter les malentendus.

En utilisant jQuery 2.1 sur les navigateurs compatibles HTML5 et CSS3, les performances changent.

Voici le scénario de test et les résultats:

function doTest(selectorCallback) {
    var iterations = 100000;

    // Record the starting time, in UTC milliseconds.
    var start = new Date().getTime();

    for (var i = 0; i < iterations; i++) {
        // Execute the selector. The result does not need to be used or assigned
        selectorCallback();
    }

    // Determine how many milliseconds elapsed and return
    return new Date().getTime() - start;
}

function start() {
    jQuery('#stats').html('Testing...');
    var results = '';

    results += "$('#parent .child'): " + doTest(function() { jQuery('#parent .child'); }) + "ms";
    results += "<br/>$('#parent > .child'): " + doTest(function() { jQuery('#parent > .child'); }) + "ms";
    results += "<br/>$('#parent').children('.child'): " + doTest(function() { jQuery('#parent').children('.child'); }) + "ms";
    results += "<br/>$('#parent').find('.child'): " + doTest(function() { jQuery('#parent').find('.child'); }) + "ms";
    $parent = jQuery('#parent');
    results += "<br/>$parent.find('.child'): " + doTest(function() { $parent.find('.child'); }) + "ms";

    jQuery('#stats').html(results);
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9, chrome=1" />
    <title>HTML5 test</title>
    <script src="//code.jquery.com/jquery-2.1.1.js"></script>
</head>
<body>

<div id="stats"></div>
<button onclick="start()">Test</button>

<div>
    <div id="parent">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
    </div>
</div>

</body>
</html>

Donc, pour 100 000 itérations, j'obtiens:

JS jQuery selector stats

(Je les ai ajoutés en img à des fins de formatage.)

Vous pouvez exécuter vous-même l'extrait de code pour le tester;)

9
Vasil Popov