Сравнивая производительность $( "# foo.bar" ) и $( ". Bar", "#foo" ),
Прокрутите вниз для сравнения getById.getByClassName
и qSA
!
Если бы мы хотели выбрать все элементы класса "bar"
, которые находятся внутри элемента с идентификатором "foo"
, мы могли бы написать это:
$( '#foo .bar' )
или это:
$( '.bar', '#foo' )
Конечно, есть и другие способы достижения этого, но ради этого вопроса давайте сравним только эти два метода.
Итак, какой из вышеперечисленных методов работает лучше? (Для чего требуется меньше времени для выполнения?)
Я написал этот тест производительности:
(function() {
var i;
console.time('test1');
for( i = 0; i < 100; i++ ) {
$('#question-mini-list .tags');
}
console.timeEnd('test1');
console.time('test2');
for( i = 0; i < 100; i++ ) {
$('.tags', '#question-mini-list');
}
console.timeEnd('test2');
})();
Вы должны выполнить его из консоли на странице Начальная страница. Мои результаты:
Firefox:
test1: ~ 90ms
test2: ~ 18 мс
Chrome:
test1: ~ 65ms
test2: ~ 30 мс
Опера:
test1: ~ 50ms
test2: ~ 100 мс
Итак, в Firefox и Chrome второй метод работает в несколько раз быстрее, как я и ожидал. Однако в Opera ситуация обратная. Интересно, что здесь происходит.
Не могли бы вы провести тест на своей машине и объяснить, почему Opera работает по-другому?
Update
Я написал этот тест, чтобы исследовать, действительно ли Opera qSA является супер-быстрым. Как оказалось, это так.
(function() {
var i, limit = 5000, test1 = 'test1', test2 = 'test2';
console.time( test1 );
for( i = 0; i < limit; i += 1 ) {
document.getElementById( 'question-mini-list' ).getElementsByClassName( 'tags' );
}
console.timeEnd( test1 );
console.time( test2 );
for( i = 0; i < limit; i += 1 ) {
document.querySelectorAll( '#question-mini-list .tags' );
}
console.timeEnd( test2 );
})();
Опять же, вам нужно запустить этот код из консоли на стартовой странице. Я использовал букмарклет Firebug Lite для IE9 (так как этот браузер не реализует console.time
).
Итак, я сравнил этот метод:
document.getelementById( 'A' ).getElementsByClassName( 'B' );
к этому методу:
document.querySelectorAll( '#A .B' );
Я выполнил выше script пять раз подряд в каждом браузере. Арифметические средства:
![enter image description here]()
(Все числа указаны в миллисекундах.)
Таким образом, производительность первого метода практически одинакова в тестируемых браузерах (16-36 мс). Однако, хотя qSA намного медленнее по сравнению с первым методом, в Opera это происходит быстрее!
Итак, оптимизация qSA возможна, мне интересно, чего ждут другие браузеры...
Ответы
Ответ 1
jQuery/Sizzle избежит использования механизма Sizzle на основе JavaScript, если браузер поддерживает querySelectorAll
, и если вы передадите действительный селектор (без пользовательских, не CSS-селекторов).
Это означает, что вы в конечном счете сравниваете реализации querySelectorAll
, предполагая, что вы тестируете браузеры, которые его поддерживают.
Существуют и другие оптимизации, которые используют jQuery или Sizzle, поэтому сложно сравнивать разные типы DOM в разных браузерах.
Поводом для производительности производительности Opera является то, что у них очень оптимизированная реализация querySelectorAll
. qSA
, будучи относительно новым методом, не был столь оптимизирован в некоторых браузерах по сравнению с более старыми методами, такими как getElementsByTagName
.
Ответ 2
И победитель....
тест 3 $('#question-mini-list').find('.tags');
- test1: 25ms
- test2: 19ms
- test3: 10ms
Два предложенных вами метода не эквивалентны.
test 1: Sizzle анализирует справа налево (не просите его искать элемент на странице, а затем ограничивать идентификатор).
test 2. Использование строки в качестве контекста обычно бесполезно, используйте элементы в качестве контекста.
test 3. Поиск элементов с идентификатором невероятно быстро. После того, как вы там, вам нужно сосредоточиться на элементе данного класса.
Ответ 3
Для справки, это на 30 раз быстрее:
document.getElementById("foo").getElementsByClassName("bar");
См. jsPerf: http://jsperf.com/jquery-selector-variations/3. Это потребует прокладки для работы в более старых версиях IE.
В то время как jQuery чрезвычайно полезен, если скорость максимальна, это не всегда лучший инструмент для задания.