Какой самый быстрый child () или find () в jQuery?

320

Чтобы выбрать дочерний узел в jQuery, можно использовать children (), но также и find ().

Например:

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

дает тот же результат, что и:

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

Теперь, какой вариант является самым быстрым или предпочтительным и почему?

Барт
источник
27
.find()и .children()не одинаковы. Последний перемещается только на один уровень вниз по дереву DOM, как дочерний селектор.
Timothy003
1
@ Timothy003 Вы описали это неправильно, первый перемещается на один уровень вниз, а не второй
Дипеш Рана
5
@DipeshRana «последний» относится к собственному предложению Тимоти003, а не к вопросу.
Джаеш Бхут
1
Спасибо, что подняли этот вопрос. Во многих случаях разница в производительности тривиальна, но в документах фактически не упоминается, что эти два метода реализованы по-разному! Во имя лучших практик полезно знать, что find()это почти всегда быстрее.
Стив Беннер
Вот почему мне никогда не нравилась «первая» или «вторая» конструкция на английском языке. Просто скажи, что ты имеешь в виду. Sheesh.
Крис Уокер

Ответы:

415

children()только смотрит на непосредственные дочерние элементы узла, в то время как find()проходит через весь DOM ниже узла, поэтому children() должен быть быстрее с учетом эквивалентной реализации Тем не менее, find()использует собственные методы браузера, в то время как children()использует JavaScript, интерпретируемый в браузере. В моих экспериментах нет большой разницы в производительности в типичных случаях.

Какой из них использовать, зависит от того, хотите ли вы рассматривать только непосредственных потомков или все узлы ниже этого в DOM, т. Е. Выбрать подходящий метод, основываясь на желаемых результатах, а не на скорости метода. Если производительность действительно является проблемой, то поэкспериментируйте, чтобы найти лучшее решение и использовать его (или посмотрите некоторые критерии в других ответах здесь).

tvanfosson
источник
9
Конечно, но что произойдет, если родительский элемент имеет только дочерние узлы? Я собираюсь сделать некоторые профилирование по этому вопросу.
Джейсон
11
Производительность детей и поиска зависит от браузера и от того, насколько сложным является DOM-поддерево для вашего поиска. В современных браузерах find () внутренне использует querySelectorAll, который легко может превзойти children () в сложном селекторе и в небольшом или умеренном поддереве DOM.
LeJared
Поможет предоставить некоторые количественные результаты ваших экспериментов.
Люк
Для меня во всех тестах с вложенностью иерархии от 5 до 20 find () всегда превосходил дочерние (). (проверено в Google Chrome 54) Я ожидал обратного. Поэтому теперь я пойду простым путем и найду (...) свои элементы вместо того, чтобы перебирать их с помощью children ().
Children
179

Этот тест jsPerf предполагает, что find () работает быстрее. Я создал более тщательный тест , и он все равно выглядит так, как будто find () превосходит children ().

Обновление: согласно комментарию tvanfosson, я создал еще один тестовый пример с 16 уровнями вложенности. find () работает медленнее только при поиске всех возможных div, но find () по-прежнему превосходит children () при выборе первого уровня div.

children () начинает опережать find (), когда существует более 100 уровней вложенности и около 4000+ делений для поиска (). Это элементарный тестовый пример, но я все еще думаю, что find () быстрее, чем children () в большинстве случаев.

Я прошелся по коду jQuery в Chrome Developer Tools и заметил, что children () внутренне выполняет вызовы sibling (), filter () и выполняет еще несколько регулярных выражений, чем find ().

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

JR.
источник
4
Кажется, что дети используют методы обхода dom, а find использует селектор api, который работает быстрее.
Топ
4
Довольно вырожденный тестовый пример, поскольку у вас есть только один уровень вложенности. Если вам нужен общий случай, вам придется установить произвольную глубину вложения и проверить производительность, так как find () проходит по более глубоким деревьям, чем children ().
tvanfosson
Если вы проверяете, находится ли определенный единственный дочерний элемент (например, event.target) в конкретном элементе dom (например, $ ('. Navbar')), то $ .contains (this, event.target) является самым быстрым (8 433 609 / секунду против 140 Кб для быстрого поиска jquery). jsperf.com/child-is-in-parent
Крис Саттингер,
92

Вот ссылка, на которой есть тест производительности, который вы можете запустить. find()на самом деле примерно в 2 раза быстрее, чем children().

Chrome на OSX10.7.6

mactive
источник
$ .contains (document.getElementById ('list'), $ ('. 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
Мацей Кравчик,
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() - поиск только по дочерним элементам соответствующих элементов (на один уровень вниз).
Нареш Кумар
источник