Co to jest najszybsze dzieci () lub find () w jQuery?

320

Aby wybrać węzeł potomny w jQuery, można użyć dzieci (), ale także find ().

Na przykład:

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

daje taki sam wynik jak:

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

Która opcja jest najszybsza lub preferowana i dlaczego?

bart
źródło
27
.find()i .children()nie są takie same. Ten ostatni przesuwa się tylko o jeden poziom w dół drzewa DOM, podobnie jak selektor potomny.
Timothy003
1
@ Timothy003 Źle opisałeś, pierwszy zjeżdża o jeden poziom niżej, a drugi
Dipesh Rana
5
@DipeshRana „ten ostatni” dotyczył własnego zdania Timothy003, a nie pytania.
Jayesh Bhoot,
1
Dziękujemy za poruszenie tego problemu. W wielu przypadkach różnica w wydajności jest banalna, ale dokumenty nie wspominają, że te dwie metody są zaimplementowane inaczej! Ze względu na najlepsze praktyki warto wiedzieć, że find()prawie zawsze jest to szybsze.
Steve Benner
Dlatego nigdy nie podobała mi się „pierwsza” lub „druga” konstrukcja w języku angielskim. Po prostu powiedz, który masz na myśli. Do licha.
Chris Walker

Odpowiedzi:

415

children()patrzy tylko na bezpośrednie elementy potomne węzła, podczas gdy find()przemierza cały DOM poniżej węzła, więc children() powinno być szybciej, biorąc pod uwagę równoważne implementacje. Jednakże find()wykorzystuje natywne metody przeglądarki, natomiast children()zastosowania JavaScript interpretować w przeglądarce. W moich eksperymentach nie ma dużej różnicy wydajności w typowych przypadkach.

Które użyć zależy od tego, czy chcesz wziąć pod uwagę tylko bezpośrednich potomków, czy wszystkie węzły poniżej tego w DOM, tj. Wybierz odpowiednią metodę w oparciu o pożądane wyniki, a nie szybkość metody. Jeśli wydajność naprawdę stanowi problem, eksperymentuj, aby znaleźć najlepsze rozwiązanie i skorzystaj z niego (lub zobacz niektóre testy porównawcze w innych odpowiedziach tutaj).

tvanfosson
źródło
9
Jasne, ale co się stanie, jeśli element nadrzędny ma tylko węzły podrzędne? Mam zamiar zrobić kilka profilów na ten temat.
jason
11
Wydajność wyszukiwania dzieci i wyszukiwania zależy od przeglądarki i od stopnia skomplikowania poddrzewa DOM. W nowoczesnych przeglądarkach find () wewnętrznie używa querySelectorAll, który z łatwością może przewyższyć child () w złożonym selektorze oraz w małym lub umiarkowanym poddrzewie DOM.
LeJared,
Pomógłby w uzyskaniu wyników ilościowych z eksperymentów.
Łukasz
Dla mnie we wszystkich testach z zagnieżdżeniem hierarchii między 5 a 20 find () zawsze przewyższał dzieci (). (testowany w Google Chrome 54) Spodziewałem się czegoś przeciwnego.
Odtąd przejdę
179

Ten test jsPerf sugeruje, że find () jest szybszy. Stworzyłem dokładniejszy test i nadal wygląda na to, że find () przewyższa dzieci ().

Aktualizacja: Zgodnie z komentarzem tvanfosson stworzyłem kolejny przypadek testowy z 16 poziomami zagnieżdżenia. find () działa wolniej tylko przy wyszukiwaniu wszystkich możliwych div, ale find () wciąż przewyższa child () przy wyborze pierwszego poziomu div.

children () zaczyna osiągać lepsze wyniki niż find (), gdy istnieje ponad 100 poziomów zagnieżdżenia i około 4000+ div do przejścia przez find (). Jest to podstawowy przypadek testowy, ale nadal uważam, że find () jest szybszy niż children () w większości przypadków.

Przeszedłem przez kod jQuery w Narzędziach dla programistów Chrome i zauważyłem, że dzieci () wewnętrznie wywołują sibling (), filter () i przechodzą przez kilka więcej wyrażeń regularnych niż find ().

find () i child () spełniają różne potrzeby, ale w przypadkach, w których find () i children () wygenerowałyby ten sam wynik, zaleciłbym użycie find ().

JR.
źródło
4
Wygląda na to, że dzieci korzystają z metod przejścia do domu, a find używa interfejsu selektora, który jest szybszy.
topek,
4
Dość zdegenerowany test, ponieważ masz tylko jeden poziom zagnieżdżenia. Jeśli chcesz ogólny przypadek, musisz ustawić dowolne głębokości zagnieżdżenia i sprawdzić wydajność, ponieważ find () przemierza głębsze drzewa niż dzieci ().
tvanfosson
Jeśli sprawdzasz, czy określony pojedynczy element potomny (np. Event.target) znajduje się w określonym elemencie dom (np. $ ('. Navbar')), wówczas $ .contains (this, event.target) jest zdecydowanie najszybszy (8,433,609 / sekundę vs 140k dla najszybszego wyszukiwania jquery). jsperf.com/child-is-in-parent
Chris Sattinger
92

Tutaj jest link z testem wydajności, który możesz uruchomić. find()jest faktycznie około 2 razy szybszy niż children().

Chrome na OSX10.7.6

aktywny
źródło
$ .contains (document.getElementById („lista”), $ („. test”) [0]) wynosi 8,433,609 / sekundę. Jeśli masz określone elementy i po prostu chcesz wiedzieć, czy B jest w A, to najlepiej. jsperf.com/child-is-in-parent
Chris Sattinger
Niezły test. Zauważ, że może być jeszcze szybciej, jeśli zrobisz coś takiego, var $test = $list.find('.test');gdzie $ list jest obiektem jQuery. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk
24

Ci, niekoniecznie dają ten sam rezultat: find()będzie Ci żadnego potomka węzła, natomiast children()dostanie tylko ty natychmiastowe dzieci pasujących.

W pewnym momencie find()było znacznie wolniej, ponieważ musiał szukać każdego węzła potomnego, który mógłby być dopasowany, a nie tylko bezpośrednich dzieci. Jednak nie jest to już prawdą; find()jest znacznie szybszy dzięki zastosowaniu natywnych metod przeglądarki.

John Feminella
źródło
1
Nie według innych odpowiedzi haha: p. Tylko wtedy, gdy masz bardzo, bardzo, bardzo duże drzewo DOM ..
pgarciacamou
1
@Camou Ta odpowiedź ma cztery lata. find()było wtedy znacznie wolniejsze!
John Feminella,
@camou mówi, że część performance brzmiała „Nie według innych odpowiedzi”. Pierwszy akapit tej odpowiedzi jest dokładny.
Don Cheadle 18.04.16
14

Żaden z pozostałych odpowiedzi rozpatrywane przypadku użycia .children()lub .find(">")do tylko szukać bezpośrednich dzieci elementu nadrzędnego. Dlatego stworzyłem test jsPerf, aby się dowiedzieć , używając trzech różnych sposobów rozróżniania dzieci.

Tak się składa, że ​​nawet przy użyciu dodatkowego selektora „>” .find()jest nadal dużo szybszy niż .children(); w moim systemie, 10x tak.

Tak więc, z mojej perspektywy, wydaje się, że nie ma żadnego powodu, aby .children()w ogóle używać mechanizmu filtrującego .

Craig Walker
źródło
3
Dziękuję za ten komentarz! Zastanawiam się, czy jQuery powinien po prostu przełączyć się na tworzenie .children (x) jako aliasu dla .find (">" + x), chociaż prawdopodobnie są inne komplikacje, o których nie myślę.
Michael Scott Cuthbert,
1
To wydaje się najbardziej odpowiednie porównanie. Dzięki!
GollyJer,
3

Zarówno find()i children()sposoby są stosowane do filtrowania dziecko dopasowanych elementów, z wyjątkiem pierwszych jest przemieszcza się dowolnym poziomie w dół, to jest on przemieszcza jeden poziom niżej.

Ułatwiać:

  1. find() - przeszukaj dziecko dopasowanych elementów, wnuka, prawnuka ... wszystkie poziomy w dół.
  2. children() - przeszukuj tylko elementy potomne dopasowanych elementów (o jeden poziom niżej).
Naresh Kumar
źródło