Was sind die schnellsten Kinder () oder find () in jQuery?

320

Um einen untergeordneten Knoten in jQuery auszuwählen, können Sie untergeordnete (), aber auch find () verwenden.

Zum Beispiel:

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

ergibt das gleiche Ergebnis wie:

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

Welche Option ist am schnellsten oder bevorzugtesten und warum?

Bart
quelle
27
.find()und .children()sind nicht gleich. Letzterer bewegt sich nur eine Ebene im DOM-Baum entlang, wie ein untergeordneter Selektor.
Timothy003
1
@ Timothy003 Sie haben es falsch beschrieben, der erstere fährt eine Ebene nach unten, nicht der letztere
Dipesh Rana
5
@ DipeshRana das 'letztere' galt für Timothy003s eigenen Satz, nicht für die Frage.
Jayesh Bhoot
1
Vielen Dank, dass Sie dieses Problem angesprochen haben. In vielen Fällen ist der Leistungsunterschied trivial, aber in den Dokumenten wird nicht erwähnt, dass diese beiden Methoden unterschiedlich implementiert sind! Aus Gründen der Best Practices ist es gut zu wissen, dass dies find()fast immer schneller ist.
Steve Benner
Deshalb hat mir die Konstruktion "die erstere" oder "die letztere" auf Englisch nie gefallen. Sagen Sie einfach, welche Sie meinen. Meine Güte.
Chris Walker

Antworten:

415

children()Betrachtet nur die unmittelbaren untergeordneten Elemente des Knotens, während find()das gesamte DOM unterhalb des Knotens durchlaufen wird, children() sollte dies bei gleichwertigen Implementierungen schneller sein. Verwendet find()jedoch native Browsermethoden, während im Browser interpretiertes JavaScriptchildren() verwendet wird. In meinen Experimenten gibt es in typischen Fällen keinen großen Leistungsunterschied.

Welche zu verwenden ist, hängt davon ab, ob Sie nur die unmittelbaren Nachkommen oder alle Knoten unter diesem im DOM berücksichtigen möchten, dh wählen Sie die geeignete Methode basierend auf den gewünschten Ergebnissen und nicht auf der Geschwindigkeit der Methode. Wenn Leistung wirklich ein Problem ist, experimentieren Sie, um die beste Lösung zu finden, und verwenden Sie diese (oder sehen Sie sich einige der Benchmarks in den anderen Antworten hier an).

Tvanfosson
quelle
9
Sicher, aber was passiert, wenn das übergeordnete Element nur untergeordnete Knoten hat? Ich werde ein Profil dafür erstellen.
Jason
11
Die Leistung von Kindern gegen Finden hängt vom Browser ab und davon, wie komplex der DOM-Teilbaum für Sie ist. In modernen Browsern findet find () intern querySelectorAll, das Kinder () in komplexen Selektoren und in kleinen bis mittelschweren DOM-Teilbäumen leicht übertreffen kann.
LeJared
Würde helfen, einige quantitative Ergebnisse Ihrer Experimente zu liefern.
Luke
Für mich hat find () in allen Tests mit Hierarchie-Verschachtelungen zwischen 5 und 20 Kinder immer übertroffen (). (getestet in Google Chrome 54) Ich habe das Gegenteil erwartet. Von nun an gehe ich den einfachen Weg und finde (...) meine Elemente, anstatt sie über Kinder () zu durchqueren. Kinder (). Kinder () ...
Ruwen
179

Dieser jsPerf-Test legt nahe, dass find () schneller ist. Ich habe einen gründlicheren Test erstellt , und es sieht immer noch so aus, als ob find () Kinder () übertrifft.

Update: Gemäß dem Kommentar von tvanfosson habe ich einen weiteren Testfall mit 16 Verschachtelungsebenen erstellt. find () ist nur langsamer, wenn alle möglichen Divs gefunden werden, find () übertrifft jedoch immer noch child (), wenn die erste Ebene von divs ausgewählt wird.

Kinder () beginnen, find () zu übertreffen, wenn mehr als 100 Verschachtelungsebenen und mehr als 4000 Divs für find () zu durchlaufen sind. Es ist ein rudimentärer Testfall, aber ich denke immer noch, dass find () in den meisten Fällen schneller ist als children ().

Ich habe den jQuery-Code in den Chrome Developer Tools durchgesehen und festgestellt, dass children () intern sibling (), filter () aufruft und einige weitere reguläre Ausdrücke durchläuft als find ().

find () und children () erfüllen unterschiedliche Anforderungen, aber in den Fällen, in denen find () und children () dasselbe Ergebnis ausgeben würden, würde ich die Verwendung von find () empfehlen.

JR.
quelle
4
Es scheint, dass Kinder Dom-Traversal-Methoden verwenden und Find die Selektor-API verwendet, die schneller ist.
Topek
4
Ziemlich entarteter Testfall, da Sie nur eine Verschachtelungsebene haben. Wenn Sie den allgemeinen Fall möchten, müssen Sie einige beliebige Verschachtelungstiefen einrichten und die Leistung überprüfen, wenn find () tiefere Bäume als untergeordnete () durchquert.
Tvanfosson
Wenn Sie überprüfen, ob sich ein bestimmtes einzelnes untergeordnetes Element (z. B. event.target) in einem bestimmten dom-Element befindet (z. B. $ ('. Navbar')), ist $ .contains (this, event.target) bei weitem das schnellste (8.433.609 / Sekunde vs 140k für die schnellste JQuery-Suche). jsperf.com/child-is-in-parent
Chris Sattinger
92

Hier ist ein Link mit einem Leistungstest, den Sie ausführen können. find()ist eigentlich etwa 2 mal schneller als children().

Chrome unter OSX10.7.6

mactive
quelle
$ .contains (document.getElementById ('list'), $ ('. test') [0]) beträgt 8.433.609 / Sekunde. Wenn Sie bestimmte Elemente haben und nur wissen möchten, ob B in A ist, ist dies am besten. jsperf.com/child-is-in-parent
Chris Sattinger
Schöner Test. Beachten Sie, dass es noch schneller sein kann, wenn Sie beispielsweise " var $test = $list.find('.test');list" als jQuery-Objekt ausführen. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk
24

Diese führen nicht unbedingt zum gleichen Ergebnis: find()Sie erhalten einen Nachkommenknoten , während Sie children()nur unmittelbare Kinder erhalten , die übereinstimmen.

Zu einem bestimmten Zeitpunkt find()war es viel langsamer, da nach jedem Nachkommenknoten gesucht werden musste, der übereinstimmen könnte, und nicht nur nach unmittelbaren Kindern. Dies ist jedoch nicht mehr wahr; find()ist aufgrund der Verwendung nativer Browsermethoden viel schneller.

John Feminella
quelle
1
Nicht nach den anderen Antworten haha: p. Nur wenn Sie einen sehr, sehr, sehr großen DOM-Baum haben ..
pgarciacamou
1
@ Camou Diese Antwort ist vier Jahre alt. find()war zu der Zeit viel langsamer!
John Feminella
@camou sagt, dass der Leistungsteil "Nicht gemäß den anderen Antworten" war. Der erste Absatz dieser Antwort ist korrekt.
Don Cheadle
14

Keiner der anderen Antworten befasste sich mit dem Fall der Verwendung .children()oder .find(">")zu nur für den sofortigen Kinder eines Elternelement zu suchen. Deshalb habe ich einen jsPerf-Test erstellt, um dies herauszufinden. Dabei wurden drei verschiedene Methoden zur Unterscheidung von Kindern verwendet.

Selbst wenn Sie den zusätzlichen ">" Selektor verwenden, .find()ist dies immer noch viel schneller als.children() ; auf meinem System 10x so.

Aus meiner Sicht scheint es also nicht viel Grund zu geben, den Filtermechanismus .children()überhaupt zu verwenden.

Craig Walker
quelle
3
Vielen Dank für diesen Kommentar! Ich frage mich, ob jQuery einfach darauf umstellen sollte, dass .children (x) ein Alias ​​für .find (">" + x) ist, obwohl es wahrscheinlich andere Komplikationen gibt, an die ich nicht denke.
Michael Scott Cuthbert
1
Dies scheint der am besten geeignete Vergleich zu sein. Vielen Dank!
GollyJer
3

Beide find()und children()Methoden werden verwendet, um das untergeordnete Element der übereinstimmenden Elemente zu filtern, außer dass das erstere eine beliebige Ebene nach unten und das letztere eine einzelne Ebene nach unten fährt.

Vereinfachen:

  1. find() - Durchsuche das Kind, Enkel, Urenkel der übereinstimmenden Elemente ... alle Ebenen nach unten.
  2. children() - Durchsuchen Sie nur das untergeordnete Element der übereinstimmenden Elemente (einzelne Ebene nach unten).
Naresh Kumar
quelle