Производительность селектора jQuery с контекстом - PullRequest
21 голосов
/ 11 марта 2010

Я читал эту статью Брэндона Аарона здесь , о том, как может помочь контекст jquery. Поэтому я подумал о том, чтобы сделать свой собственный тест. Вот что я сделал.

  1. Создан DIV с id = "context" и вложенный DIV с id = "holder" в "#context", созданном ранее.

  2. Создание вложенных DIV глубиной 18 и добавление <div id="context"><div id="holder"></div></div> к нему, в результате чего получается 20 вложенных DIV

  3. Теперь я проверил время, необходимое для доступа к «#holder» с помощью следующих селекторов:
    а. $("#holder") // no context
    б. $("#holder", "#context") // with "#context" selector string
    с. $("#holder", $("#context")) // sending jquery object each time with selector "#context"
    д. $("#holder", $context) // where, var $context = $("#context"). Caching jquery obj
    В каждом из случаев был отмечен X = 1000 раз, а также разница времени начала и окончания. Я нашел это время, потраченное на:
    случай (а) был наименее последовательным 28-32 мсек [jquery-1.3.2]
    случай (b) + (c) имел самые высокие времена 60-65 мс и 70-75 мс соответственно
    Случай (d) имел 40-50 мсек с 1 или 2 значениями с шипами.

Действителен ли этот тип базовой проверки? Вы можете играть с кодом JS здесь в JSBIN. [Дайте мне знать, если я смогу улучшить этот тест, как-то]
Если ДА, то как этот «контекст» действительно помогает?


# ЗАМЕЧАНИЕ: также замените jquery-1.3.2 на jquery-1.4.2 в режиме редактирования jsbin, и вы будете удивлены, увидев, как увеличиваются числа: P

Ответы [ 6 ]

30 голосов
/ 11 марта 2010

Контекст действительно помогает, когда у вас гораздо больший DOM, который вы просматриваете. Поиск идентификаторов уже очень быстрый, и контекст не очень помогает в этом случае. Контекст действительно может иметь значение, когда вы выбираете по имени тега или по классу.

Попробуйте провести тестирование так: http://jsbin.com/aciji4/4

вы действительно можете увидеть, как время становится лучше для контекста, когда вы увеличиваете количество элементов в DOM, например:

4 голосов
/ 11 марта 2010

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

$('#context').find('#holder');

В основном я вижу это как более простой способ идентифицировать элементы в событиях и итераторах, где контекст меняется, потому что

$('.holder', this)

красивее

$(this).find('.holder')
3 голосов
/ 27 сентября 2012

Что бы это ни стоило, $context = $("#context") все еще использует объект jQuery, который затем должен быть преобразован в объект DOM.

Если вы используете $context = $("#context")[0], вы обнаружите, что он работает так же быстро, как и первый тест.

3 голосов
/ 11 марта 2010

Селектор #ID использует браузер native document.getElementById. Это будет быстро, несмотря ни на что.

Попробуйте использовать селектор типа div.class [attribute = value] с контекстом и без него. Например, * вы можете выбрать ссылку «Связанные» вопроса справа с помощью этого селектора:

// Selects anchor elements with href's beginning with /questions/
$('a[href^=/questions/]')

Но быстрее ограничить, сколько якорных элементов должен перебирать механизм селектора, оценивая это относительно дорогое сопоставление текста:

$('a[href^=/questions/]', '.related')

* И игнорирование очевидно более простого класса .question-hyperlink для этих ссылок, ради обсуждения.

1 голос
/ 27 марта 2013

Будьте осторожны, прежде чем приступить к рефакторингу своего кода. Как написано в #NOTE, jQuery начиная с 1.4 работает совершенно по-другому. Последняя версия может содержать еще больше оптимизаций.

Я изменил код jsbin, приведенный выше, чтобы иметь недавний jQuery, а также добавил несколько дополнительных случаев. Вы увидите, что только те три (2,3,6) случая получили снижение производительности, которое создает еще один объект jQuery за раунд. Отдых проходит в одно и то же время.

Вы можете найти модифицированную версию здесь: http://jsbin.com/aciji4/63/

1 голос
/ 10 ноября 2011

Я взял код JSBin и поместил его в jsPerf Test

$ context.find ('. Holder') в раза в два раза быстрее , чем его ближайший конкурент, $ ('. Holder', $ context), что на в десять раз быстрее , чем любой другой используемый селектор.

В заключение, кэшируйте ваши селекторы и используйте .find () для максимальной производительности

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...