Вопрос

У меня огромные различия в производительности в зависимости от того, как я выражаю свои селекторы.Например, посмотрите на эти 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, которое показывает, сколько раз функция была оценена.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top