Производительность селектора jQuery
-
05-07-2019 - |
Вопрос
У меня огромные различия в производительности в зависимости от того, как я выражаю свои селекторы.Например, посмотрите на эти 2 селектора, которые выбирают точно такие же элементы:
A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input")
B) someTableRow.find("td.someColumnClass span.editMode input")
Я бы ожидал, что B) будет быстрее, поскольку есть только 1 вызов, но на самом деле я нахожу, что A) выполняется примерно в 8 раз быстрее.Я понятия не имею, почему, у кого-нибудь есть какое-нибудь представление?Спасибо
Решение
Предполагая, что вы используете хотя бы jQuery 1.3 (т.е. с добавлением Sizzle), производительность, которую вы видите, связана с изменением, в котором обходится DOM. С здесь :
До jQuery 1.2.6 включительно Селекторный двигатель работал в режиме «сверху вниз» (или "слева направо"). JQuery В 1.3.x (т. Е. Sizzle , в который встраивается jQuery) введена функция «снизу вверх» ; (или же "справа налево") подход к запросам ДОМ.
Во втором примере ( " td.someColumnClass span.editMode input "
) Sizzle эффективно делает это:
input
внутри someTableRow
input
просмотрите его дерево предков для элементов span
с помощью class = " editMode "
. Удалите элементы input
, у которых нет этих предков span.editMode
просмотрите его дерево предков для элементов td
с помощью class = " someColumnClass "
. Удалите элементы input
, у которых нет этих предков Однако в первом примере вы явно определяете каждый шаг при каждом вызове find ()
, определяя контекст и проходя оттуда вниз . Вы применяете «сверху вниз» подход. Это эквивалентно передаче в контексте на каждом шаге, который является обычно считается повышением производительности :
$('input', $('span.editMode', $('td.someColumnClass', someTableRow)))
Другие советы
Потому что вы сокращаете контекст для поиска.
В случае B необходимо выполнить поиск по каждому элементу DOM, чтобы убедиться, что он соответствует критериям.
В случае A is может быстро принять решение игнорировать все, что не является «td.someColumnClass», тогда он может взять это подмножество DOM и игнорировать все, что не входит в «span.editMode». Таким образом, он имеет гораздо меньший набор элементов для поиска, чтобы найти «вход» сейчас.
А больше звонков, но проще. Б один звонок, но более сложный. В этом случае сложность вызова значительно превышает количество вызовов.
По моему опыту, способ, которым jQuery обрабатывает селекторы, немного отличается от CSS.
Сокращение контекста поиска - это ключ, как отметил Джош.
Я нахожу использование двух селекторов параметров действительно быстрым
Как это соотносится со скоростью?
Вам не нужны здесь все переменные, это просто для того, чтобы было ясно, что я делаю.
var columnClasses = $('.someColumnClass');
var tableCell = $('td', columnclasses);
var editMode = $('.editmode', tableCell);
var spanInside = $('span', editMode);
var inputFinally = $('input', spanInside);
Доброта,
Dan
Я провел небольшое исследование производительности jQuery Selector. Большая проблема - поиск по имени класса в Internet Explorer. IE не поддерживает getElementsByClassName - поэтому jQuery и другие фреймворки «переопределяют» это в JavaScript путем перебора всех элементов DOM. Посетите следующий аналитический блог о производительности jQuery Selector а> р>
Здесь есть действительно интересная статья о производительности селектора: http: // blogs .atlassian.com / разработчик / 2009/08 / jquery_bondage.html
В нем автор показывает «bind» Расширение jQuery, которое показывает, сколько раз функция была оценена.