В современных браузерах реализованы родные методы querySelectorAll и querySelector, которые позволяют простой отбор элементов в DOM в одну строчку используя синтаксис CSS, при этом без подключения jQuery. Во многих статьях в интернете я читал, что этот метод очень оптимизирован и делает очень быстрый перебор элементов. На сколько это правда, решил проверить проведя тесты.
Итак, заверстываем небольшую страницу:
<!DOCTYPE html>
<html>
<head>
<title>Тест производительности javascript</title>
<meta charset="utf-8">
</head>
<body>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div id="a1">
<input type="radio">
<input type="radio">
<input type="radio">
<input type="radio">
<input type="radio">
</div>
<div id="a2">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div>
<div id="a3">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</div>
</body>
</html>
В верстке у нас 8 DIVов(5 из них с классом) и 15 инпутов(по 5 текстовых, радио и чекбоксов).
Тестироварь производительность работы разных методов будем через цикл, путем замерения времени в начале и в конце цикла. Цикл выполнит операцию сто тысяч раз.
var start = new Date()
for (var i=0;i<100000;i++){
//тестируемый код
}
var end = new Date()
var speed = end.getTime()-start.getTime()
Конфигурация системы:
- ОС: Windows 7 x32
- Память: 1Гб
- Процессор: Dual-Core e5400 2.7Ггц
Тестирование проходит в браузерах:
- Firefox 7.01
- Opera 11.51
- Internet Explorer 9
- Google Chrome 14
Для более точного тестирования, все тесты провел 10 раз и в результатах показываю среднее значение. Результаты показаны в милисекундах. Естественно, чем меньше число, тем лучше.
Начнем с простого и очень популярного примера, поиска элемента по id:
var el = document.getElementById("a1")
Результат:
- Firefox 16
- Opera 45
- Internet Explorer 76
- Google Chrome 21
А теперь попробуем тоже самое, но через querySelector
var el = document.querySelector("#a1")
Результат:
- Firefox 166
- Opera 282
- Internet Explorer 295
- Google Chrome 327
Как видно из результатов, он оказался медленнее примерно в 10 раз в Firefox, в 5 Opera, в 4 в IE9 и где-то в 15 раз в Хроме.
Теперь найдем все инпуты на странице.
var el = document.getElementsByTagName("input")
- Firefox 21
- Opera 82
- Internet Explorer 122
- Google Chrome 29
Теперь через querySelectorAll.
var el = document.querySelectorAll("input")
- Firefox 475
- Opera 40
- Internet Explorer 570
- Google Chrome 732
В Опере он оказался в 2 раза быстрее, а в остальных браузерах гораздо медленее.
Ищем элементы по классу:
var el = document.getElementsByClassName("block")
- Firefox 29
- Opera 83
- Internet Explorer 119
- Google Chrome 25
Тоже самое через querySelectorAll.
var el = document.querySelectorAll(".block")
- Firefox 421
- Opera 40
- Internet Explorer 574
- Google Chrome 750
Результаты как и в предыдущем примере. Опера с querySelectorAll работает быстрее в два раза, чем через getElementsByClassName. Другие браузеры наоборот медленее, причем с нехилой разницей.
Теперь найдем все инпуты внутри контейнера с id=«a3»
var el = document.getElementById("a3").getElementsByTagName("input")
- Firefox 42
- Opera 110
- Internet Explorer 200
- Google Chrome 43
А теперь так:
var el = document.querySelectorAll("#a3 input")
- Firefox 630
- Opera 41
- Internet Explorer 633
- Google Chrome 985
Хром показал самые плохие результаты, как и в предыдущем тесте, чему я кстати был сильно удивлен. В Опере через селекторы опять работают быстрее.
Теперь попробуем более сложную задачу. Найдем все радио и чекбокс инпуты. Сначала мы находим все инпуты, затем через цикл проверяем их type и если совпадает, то кладем элемент в массив.
var radio_checkbox = []
for(var j=0, inputs = document.getElementsByTagName("input"), len = inputs.length;j<len;j++){
var type = inputs[j].type
if(type=="radio" || type=="checkbox"){
radio_checkbox.push(inputs[j])
}
}
- Firefox 1027
- Opera 1122
- Internet Explorer 2012
- Google Chrome 829
Теперь тот же результат одной строчкой.
var el = document.querySelectorAll("input[type='radio'],input[type='checkbox']")
- Firefox 1053
- Opera 42
- Internet Explorer 3025
- Google Chrome 1414
В Firefox скорость можно считать одинаковой. В IE и Chrome через querySelectorAll оказалось медленее примерно в 1.5 раза. А Опера показала невероятно быстрый результат по сравнению с циклом, в 20 с лишним раза быстрее.
Поиск элементов используя querySelectorAll действительно очень удобный и позволяет сильно упростить код. Надеюсь, что производители браузеров оптимизируют в будущем эти методы. Тем более, даже IE8 неплохо поддерживает этот метод(только в рамках CSS2). А пока только Opera демонстрирует быстроту этого метода по сравнению с getElement(s).
UPD: по рекомендации barmaley_exe решил вывести здесь ссылки на альтернативный тест онлайн:
- Поиск по id тест
- Поиск по имени тега тест
- Поиск по классу тест
- Поиск инпутов внутри определенного контейнера тест
- Поиск радио и чекбоксов тест. Замечу, что вариант через онлайн сервис показал другую разницу в скорости, нежели просто проверкой в браузере, которая используется в статье.
Источник: Хабрахабр - JavaScript
Оригинальная страница: [Из песочницы] Методы querySelectorAll и querySelector. Так ли они быстры на самом деле?
Комментариев нет:
Отправить комментарий