Що найшвидше дітей () або знайти () у 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.