Минимизация экземпляра jQuery против создания большего количества экземпляров
Я начал серию публикаций по оптимизации javascript / jQuery и наткнулся на этот интересный результат.
Почему минимизация объектов jQuery (путем поиска в кэшированной коллекции jQuery) может быть медленнее, чем создание большего количества экземпляров объектов jQuery?
Я был ошеломлен, увидев результаты теста, который я подготовил. Я всегда думал, что минимизировать создание $ экземпляров медленнее.
Это то, что я привык писать, поскольку я кэширую родителя (я называю это "appRoot").
var appRoot = $("#appRoot");
appRoot.find(".element1").css("color","red");
appRoot.find(".element2").css("color","blue");
против
$(".element1").css("color","red");
$(".element2").css("color","blue");
Смотрите результаты теста (немного другой сценарий). http://jsperf.com/minimize-jquery-object-creation/2, оказывается, что кэшированный фрагмент медленнее, чем некэшированный фрагмент.
Я пытаюсь понять почему?
3 ответа
Вы должны учитывать, что ваш тест содержит менее 10 делений или других HTML-элементов. Причина написания кода, как в первом примере, состоит в том, чтобы сделать селектор быстрее, но за счет дополнительных вызовов метода. Обычно селектор должен быть более дорогим из двух, поэтому выигрыш будет превышать потери, но с таким маленьким DOM селектор будет очень дешевым, независимо от того, как вы его напишите.
Люди часто делают ошибку, не помня, что более сложный и большой DOM изменит узкие места кода. Я думаю, что jsperf должен иметь какое-то предупреждение об этом.
Я думаю, что вызов find() замедляет процесс.
Единственная причина для кеширования объекта jQuery - если вы собираетесь ссылаться на него или манипулировать им несколько раз. Если вы просто устанавливаете свойство CSS, и это свойство не будет изменяться в течение срока службы отображаемой страницы, то нет смысла определять переменную кэша.
Я думаю, это потому, что в "больше объектов jquery создано", jQuery может напрямую использовать недавний API
document.getElementsByClassName("classvalue")
в другом случае с "less jquery" вы должны всегда проверять, что найденный элемент находится под #appRoot, что занимает больше времени.
Вот еще один тест, использующий document в качестве appRoot, который, похоже, немного сокращает разрыв во втором запуске: http://jsperf.com/minimize-jquery-object-creation/6