Що найшвидше дітей () або знайти () у jQuery?


320

Для вибору дочірнього вузла в jQuery можна скористатись дітьми (), але також знайти ().

Наприклад:

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

дає такий же результат, як:

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

Тепер, який варіант найшвидший чи кращий і чому?


27
.find()і .children()не однакові. Останній рухається лише на один рівень вниз по дереву DOM, як дочірній селектор.
Тимофій003,

1
@ Timothy003 Ви описали це неправильно, колишній подорожує на один рівень вниз, а не останній
Діпеш Рана

5
@DipeshRana "останній" застосовується до власного речення Тимофія003, а не до питання.
Jayesh Bhoot

1
Дякуємо, що підняли цю проблему. У багатьох випадках різниця в продуктивності тривіальна, але документи фактично не згадують, що ці два методи реалізуються по-різному! Заради найкращих практик добре знати, що find()це майже завжди швидше.
Стів Беннер

Ось чому мені ніколи не сподобалася «перша» чи «остання» конструкція англійською мовою. Просто скажіть, про який ви маєте на увазі. Шиш.
Кріс Уокер

Відповіді:


415

children()дивиться лише на безпосередніх дітей вузла, тоді як find()проходить весь DOM нижче вузла, тому children() слід швидше давати еквівалентні реалізації. Однак, find()використовуються нативні методи браузера, в той час як children()використовується інтерпретація JavaScript у браузері. У моїх експериментах немає великої різниці в продуктивності в типових випадках.

Що використовувати, залежить від того, чи хочете ви врахувати лише найближчих нащадків або всі вузли нижче цього у DOM, тобто виберіть відповідний метод, виходячи з бажаних результатів, а не швидкості методу. Якщо ефективність справді є проблемою, то експериментуйте, щоб знайти найкраще рішення та скористайтеся цим (або подивіться деякі орієнтири в інших відповідях тут).


9
Звичайно, але що станеться, якщо батьківський елемент має лише дочірні вузли? Я збираюся зробити кілька профілів на цьому.
Ясон

11
Ефективність дітей та пошуку залежить від того, наскільки браузер є тим, наскільки складним є DOM-піддерево у вашому пошуку. У сучасних браузерах знаходять () внутрішньо використовує querySelectorAll, який легко може перевершити дітей () у складному селекторі та на малому та помірному піддереві DOM.
LeJared

Може допомогти забезпечити деякі кількісні результати ваших експериментів.
Лука

Для мене в усіх тестах з ієрархією вкладень між 5 і 20 знаходять () завжди перевершують дітей (). (перевірено в Google Chrome 54) Я очікував зворотне. Отже, відтепер я пройду легкий шлях і знайду (...) мої елементи, а не обходжу їх через діти (). Діти (). Діти () ...
Рувен

179

Цей тест jsPerf говорить про те, що пошук () швидше. Я створив більш ретельний тест , і він все ще виглядає так, ніби знайти () перевершує дітей ().

Оновлення: Відповідно до коментаря tvanfosson, я створив ще один тестовий випадок з 16 рівнями вкладення. find () лише повільніше, коли знаходять усі можливі діви, але find () все ж перевершує дітей () при виборі першого рівня divs.

діти () починають перевершувати пошук (), коли існує понад 100 рівнів гніздування та близько 4000+ дивок для пошуку (), щоб перейти. Це рудиментарний тестовий випадок, але я все ж думаю, що пошук () у більшості випадків швидше, ніж діти ().

Я переглянув код jQuery в Інструментах для розробників Chrome і помітив, що діти () внутрішньо здійснюють дзвінки до sibling (), filter () і проходять ще кілька регексів, ніж find ().

find () та діти () задовольняють різні потреби, але у випадках, коли find () та діти () дають однаковий результат, я б рекомендував використовувати find ().


4
Здається, діти використовують методи обходу дому та знаходять використання селектора api, що швидше.
топек

4
Досить вироджений тестовий випадок, оскільки у вас є лише один рівень гніздування. Якщо вам потрібно загальний випадок, вам доведеться встановити довільну глибину гніздування і перевірити продуктивність, оскільки find () обходить глибші дерева, ніж діти ().
tvanfosson

Якщо ви перевіряєте, чи є певний сингулярний дочірній елемент (наприклад, event.target) у певному елементі dom (напр., $ ('. Navbar')), то $ .contains (це, event.target) на сьогоднішній день найшвидший. (8,433,609 / секунда - 140 к. Для найшвидшого пошуку jquery). jsperf.com/child-is-in-parent
Кріс Саттінгер

92

Ось посилання, яке містить тест на ефективність, який ви можете запустити. find()насправді приблизно в 2 рази швидше, ніж children().

Chrome на OSX10.7.6


$ .contains (document.getElementById ('список'), $ ('. test') [0]) становить 8,433,609 / секунду. Якщо у вас є конкретні елементи і ви просто хочете дізнатись, чи є B в A, то це найкраще. jsperf.com/child-is-in-parent
Кріс Саттінгер

Хороший тест. Зауважте, що це може бути навіть швидше, якщо ви зробите щось на зразок того, var $test = $list.find('.test');де $ list є об'єктом jQuery. jsperf.com/jquery-selectors-context/101
Maciej Krawczyk

24

Вони не обов'язково дадуть однаковий результат: find()ви отримаєте будь-який нащадковий вузол, тоді як children()ви отримаєте лише безпосередніх дітей, які відповідають.

В один момент це find()було набагато повільніше, оскільки йому доводилося шукати кожен нащадковий вузол, який міг би відповідати, а не лише безпосередньо дітей. Однак це вже не відповідає дійсності; find()набагато швидше завдяки використанню власних методів браузера.


1
Не відповідно до інших відповідей ха-ха: с. Тільки тоді, коли у вас дуже-дуже-дуже велике дерево DOM ..
pgarciacamou

1
@Camou Цій відповіді чотири роки. find()було набагато повільніше на той час!
Джон Фемінелла

@camou каже, що в перформансі було "Не за іншими відповідями". Перший абзац цієї відповіді точний.
Дон Чідл

14

Жоден з інших відповідей не розглядаються в разі використання .children()або .find(">")для тільки пошуку безпосередніх дітей батьківського елемента. Отже, я створив тест jsPerf, щоб з’ясувати це , використовуючи три різні способи розрізнення дітей.

Як це буває, навіть при використанні додаткового селектора ">" .find()все ще набагато швидше, ніж .children(); у моїй системі, 10 разів так.

Отже, з моєї точки зору, мабуть, немає причин використовувати механізм фільтрації .children()взагалі.


3
Дякую за цей коментар! Цікаво, чи jQuery повинен просто перейти на створення .children (x) псевдонімом для .find (">" + x), хоча, ймовірно, є й інші ускладнення, про які я не думаю.
Майкл Скотт Катберт

1
Це здається найбільш підходящим порівнянням. Дякую!
GollyJer

3

Обидва find()та children()методи використовуються для фільтрації дочірніх зіставлених елементів, за винятком того, що перше переміщує будь-який рівень вниз, другий - пересувається на один рівень вниз.

Щоб спростити:

  1. find() - пошук за дитиною, онуком, правнуком відповідних елементів… всі рівні вниз.
  2. children() - шукати лише дочірні елементи відповідних елементів (один рівень вниз).
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.