Почему функция селектора jQuery настолько медленна по сравнению с собственными методами DOM
Я знаю, что эта тема обсуждалась в целом уже несколько раз, но я ищу более подробную техническую и подробную информацию, чтобы понять, что происходит на самом деле.
Я разработал серию тестов, чтобы сравнить скорость jQuery самых основных селекторов "#id" и ".class" с различными собственными методами DOM.
Я хочу, чтобы выяснить, почему результаты являются тем, чем они являются.
Вот тесты: http://jsperf.com/jqueryspeed
Самое главное, что getElementById является самым быстрым из всех.
Для сравнения я добавил как jQuery ('# id'), так и jQuery.fn.init('# id') в качестве тестов, разница между ними заключается в том, что первый из них запускает целый новый объект jQuery, а второй запускает только прототипную функцию и, следовательно, быстрее. Таким образом, разница между этими двумя понятна.
Основное отличие, которое я НЕ понимаю, это огромный разрыв между скоростью getElementById и скоростью jQuery.fn.init, который имеет простой тест для обработки простого ('#id') запроса в конкретным способом, возвращаясь к вызову getElementById.
Итак, почему, например, в Chrome, этот метод примерно в 8 раз медленнее, чем исходный, хотя он в основном является для него только оболочкой?
Он также примерно в 3-4 раза медленнее, чем обернутый getElementById $(document.getElementById('# id'))...
Любые идеи, пожалуйста?
Ответы
Ответ 1
Это количество кода, через которое проходит jquery, когда мы используем простой $ ('селектор')
http://james.padolsey.com/jquery/#v=1.10.2&fn=init
Как видите, много проверок, совпадений с регулярными выражениями, кросс-браузерных трюков и т.д.
Важно понимать, что jquery - это библиотека, построенная на javascript. Javascript выполняется непосредственно в браузере. Где jquery обрабатывает довольно много кода javascript перед его выполнением браузером.
Я лично предпочитаю jquery. Я действительно не беспокоюсь о том, чтобы экономить эти нано секунды. Уровень простоты, который обеспечивает jquery, феноменален и сам по себе является произведением искусства.
Ответ 2
Нет ничего, что jQuery может сделать так же быстро, как нативный javascript, и это не просто так: он делает все возможное, чтобы сделать ваш код кросс-браузерным и простым в использовании. Он строит объект jQuery из большинства вызовов методов. В этом отношении jQuery будет намного медленнее, чем наименьший требуемый путь к данным, потому что он хочет предложить функции, которые готовы к использованию.
Давайте сравним эти два "похожих" вызова:
document.getElementById("box")
: собственный метод, который выполняет простую операцию поиска на более низком уровне, чем JavaScript. Затем он возвращает элемент DOM, который уже загружен в память. Это один из самых быстрых методов.
$('#box')
: Здесь jQuery начнется с некоторого анализа того, что вы просите его сделать. Например, он подтвердит, что это правильно сформированный селектор, а затем попытается распознать, какой это тип селектора. По завершении проверки он попытается получить элемент с идентификатором "box". После этого он создаст новый объект jQuery, заполнив его каждым ожидаемым атрибутом и убедившись, что все браузеры (и более старые браузеры тоже) получают одинаковые результаты. Это включает в себя множество откатов и тестов на соответствие. Когда объект готов к использованию, вы получаете элемент с идентификатором "box". Не так просто, как getElementById()
. Когда функции jQuery не требуются для целевого элемента, многие предпочитают использовать getElementById('box')
вместо $('#box')
.
ОБНОВЛЕНИЕ - 15/02/17:
Поскольку jQuery> = 2.0 больше не поддерживает печально известный IE 6/7/8, некоторые тесты совместимости больше не нужны, что делает jQuery легче и быстрее. Общая производительность может быть улучшена с помощью jQuery> = 2.0 вместо 1.x, если вам не требуется поддержка старых браузеров.
Ответ 3
Я добавил еще один тестовый пример для jQuery.fn.init(document.getElementById('id'))
, который был быстрее, чем большинство других методов, потому что он не выполняет ни синтаксического анализа, ни создания нового объекта jQuery (он был на 50% ниже getElementById, jsperf), и когда я вижу источник кода jquery, который выполняется во время вызова jQuery.fn.init
:
function (selector, context, rootjQuery){
if (selector.nodeType) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
}
Я могу только заключить, что инженеры Chrome и Firefox отлично справились с оптимизацией собственных операций DOM.