Подтвердить что ты не робот

Производительность селектора jQuery с контекстом

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

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

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

  • Теперь я проверил время, затрачиваемое на доступ к "#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. [Дайте мне знать, если я смогу улучшить этот тест каким-то образом]
Если ДА, то как этот "контекст" действительно помогает?


#NOTE: также замените jquery-1.3.2 на jquery-1.4.2 в режиме редактирования jsbin, и вы будете удивлены, увидев, что цифры растут: P

4b9b3361

Ответ 1

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

Попробуйте протестировать следующим образом: http://jsbin.com/aciji4/4

вы действительно можете увидеть, что время становится лучше для контекста, когда вы увеличиваете количество элементов в DOM следующим образом: http://jsbin.com/aciji4/6 p >

Ответ 2

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

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

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

$('.holder', this)

лучше, чем

$(this).find('.holder')

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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