Quels sont les enfants les plus rapides () ou find () dans jQuery?

320

Pour sélectionner un nœud enfant dans jQuery, on peut utiliser children () mais aussi find ().

Par exemple:

$(this).children('.foo');

donne le même résultat que:

$(this).find('.foo');

Maintenant, quelle option est la plus rapide ou préférée et pourquoi?

Bart
la source
27
.find()et .children()ne sont pas les mêmes. Ce dernier ne parcourt qu'un seul niveau dans l'arborescence DOM, comme un sélecteur d'enfant.
Timothy003
1
@ Timothy003 Vous l'avez mal décrit, l'ancien ne descend pas d'un seul niveau
Dipesh Rana
5
@DipeshRana le «dernier» s'est appliqué à la propre phrase de Timothy003, pas à la question.
Jayesh Bhoot
1
Merci d'avoir soulevé ce problème. Dans de nombreux cas, la différence de performances est triviale, mais les documents ne mentionnent pas réellement que ces deux méthodes sont implémentées différemment! Par souci de bonnes pratiques, il est bon de savoir que find()c'est presque toujours plus rapide.
Steve Benner
C'est pourquoi je n'ai jamais aimé la construction "l'ancien" ou "le dernier" en anglais. Dites simplement laquelle vous voulez dire. Sheesh.
Chris Walker

Réponses:

415

children()ne regarde que les enfants immédiats du nœud, tout en find()parcourant tout le DOM sous le nœud, donc children() devrait être plus rapide compte tenu des implémentations équivalentes. Cependant, find()utilise des méthodes de navigateur natives , tout en children()utilisant JavaScript interprété dans le navigateur. Dans mes expériences, il n'y a pas beaucoup de différence de performances dans les cas typiques.

La méthode à utiliser dépend de si vous souhaitez uniquement prendre en compte les descendants immédiats ou tous les nœuds inférieurs à celui-ci dans le DOM, c'est-à-dire choisir la méthode appropriée en fonction des résultats que vous souhaitez, et non de la vitesse de la méthode. Si les performances sont vraiment un problème, essayez de trouver la meilleure solution et utilisez-la (ou consultez certains des benchmarks dans les autres réponses ici).

tvanfosson
la source
9
Bien sûr, mais que se passe-t-il si l'élément parent n'a que des nœuds enfants? Je vais faire un profilage à ce sujet.
jason
11
Les performances des enfants par rapport à find dépendent du navigateur et de la complexité de la recherche du sous-arbre DOM. Sur les navigateurs modernes, find () utilise en interne querySelectorAll qui peut facilement surpasser les enfants () dans un sélecteur complexe et sur une sous-arborescence DOM petite à modérée.
LeJared
Aiderait à fournir des résultats quantitatifs de vos expériences.
Luke
Pour moi, dans tous les tests avec des imbrications de hiérarchie entre 5 et 20, find () a toujours surpassé les enfants (). (testé dans Google Chrome 54) Je m'attendais à l'inverse. Donc à partir de maintenant, je vais prendre la voie facile et trouver (...) mes éléments au lieu de les parcourir via children (). Children (). Children () ...
Ruwen
179

Ce test jsPerf suggère que find () est plus rapide. J'ai créé un test plus approfondi , et il semble toujours que find () surpasse les enfants ().

Mise à jour: selon le commentaire de tvanfosson, j'ai créé un autre cas de test avec 16 niveaux d'imbrication. find () n'est plus lent que lors de la recherche de tous les divs possibles, mais find () surpasse toujours les enfants () lors de la sélection du premier niveau de divs.

children () commence à surperformer find () lorsqu'il y a plus de 100 niveaux d'imbrication et environ 4000+ divs pour find () à parcourir. C'est un cas de test rudimentaire, mais je pense toujours que find () est plus rapide que children () dans la plupart des cas.

J'ai parcouru le code jQuery dans Chrome Developer Tools et j'ai remarqué que children () appelle en interne sibling (), filter () et passe par quelques regex plus que find ().

find () et children () répondent à des besoins différents, mais dans les cas où find () et children () produiraient le même résultat, je recommanderais d'utiliser find ().

JR.
la source
4
Il semble que les enfants utilisent des méthodes de traversée dom et find utilise l'api du sélecteur, qui est plus rapide.
topek
4
Cas de test assez dégénéré car vous n'avez qu'un seul niveau d'imbrication. Si vous voulez le cas général, vous devrez configurer des profondeurs d'imbrication arbitraires et vérifier les performances car find () traverse des arbres plus profonds que children ().
tvanfosson
Si vous vérifiez si un élément enfant singulier spécifique (par exemple, event.target) se trouve dans un élément dom spécifique (par exemple, $ ('. Navbar')), alors $ .contains (this, event.target) est de loin le plus rapide (8 433 609 / seconde contre 140 000 pour la recherche jquery la plus rapide). jsperf.com/child-is-in-parent
Chris Sattinger
92

Voici un lien contenant un test de performances que vous pouvez exécuter. find()est en fait environ 2 fois plus rapide que children().

Chrome sur OSX10.7.6

mactive
la source
$ .contains (document.getElementById ('list'), $ ('. test') [0]) est de 8 433 609 / seconde. Si vous avez des éléments spécifiques et que vous voulez simplement savoir si B est dans A, c'est le mieux. jsperf.com/child-is-in-parent
Chris Sattinger
Joli test. Notez que cela peut être encore plus rapide si vous faites quelque chose comme var $test = $list.find('.test');où $ list est un objet jQuery. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk
24

Ceux-ci ne donneront pas nécessairement le même résultat: find()vous obtiendrez n'importe quel nœud descendant , alors children()que vous ne recevrez que des enfants immédiats qui correspondent.

À un moment donné, cela a find()été beaucoup plus lent car il a dû rechercher tous les nœuds descendants pouvant correspondre, et pas seulement les enfants immédiats. Cependant, ce n'est plus vrai; find()est beaucoup plus rapide grâce à l'utilisation de méthodes de navigation natives.

John Feminella
la source
1
Pas selon les autres réponses haha: p. Ce n'est que lorsque vous avez un très, très, très grand arbre DOM ..
pgarciacamou
1
@Camou Cette réponse a quatre ans. find()était beaucoup plus lent à l'époque!
John Feminella
@camou dit que la partie performance était "Pas selon les autres réponses". Le premier paragraphe de cette réponse est exact.
Don Cheadle
14

Aucune des autres réponses ne traitait du cas de l'utilisation .children()ou .find(">")de la recherche uniquement des enfants immédiats d'un élément parent. J'ai donc créé un test jsPerf pour le découvrir , en utilisant trois façons différentes de distinguer les enfants.

En fait, même lorsque vous utilisez le sélecteur supplémentaire ">", il .find()est encore beaucoup plus rapide que .children(); sur mon système, 10x donc.

Donc, de mon point de vue, il ne semble pas y avoir beaucoup de raisons d'utiliser le mécanisme de filtrage .children().

Craig Walker
la source
3
Merci pour ce commentaire! Je me demande si jQuery devrait simplement passer à faire de .children (x) un alias pour .find (">" + x), bien qu'il y ait probablement d'autres complications auxquelles je ne pense pas.
Michael Scott Cuthbert
1
Cela semble être la comparaison la plus appropriée. Merci!
GollyJer
3

Les deux méthodes find()et children()sont utilisées pour filtrer l'enfant des éléments correspondants, sauf que le premier descend d'un niveau, le second descend d'un seul niveau.

Pour simplifier:

  1. find() - recherchez l'enfant, le petit-enfant, l'arrière-petit-enfant des éléments appariés ... tous les niveaux plus bas.
  2. children() - recherche dans l'enfant des éléments correspondants uniquement (niveau inférieur).
Naresh Kumar
la source