Является ли jQuery каким-либо кэшированием «селекторов»?
Например, будет ли первый fragment кода выполнять полный поиск дважды, или он достаточно умен, чтобы кэшировать результаты, если никаких изменений DOM не произошло?
if ($("#navbar .heading").text() > "") { $("#navbar .heading").hide(); }
а также
var $heading = $("#navbar .heading"); if ($heading.text() > "") { $heading.hide(); }
Если селектор более сложный, я могу себе представить, что это нетривиальный хит.
- Селектор jQuery для метки флажка
- поиск jQuery и контекст
- jQuery выбрать все, кроме первого
- Случай селектора CSS для атрибутов
- Селектор jQuery: Id заканчивается?
- Как изменить css display none или заблокировать свойство с помощью JQuery?
- jQuery выбирает атрибут с использованием операторов AND и OR
- Как выбрать конкретный элемент формы в jQuery?
- Получить список отмеченных флажков в div с помощью jQuery
- jQuery ИЛИ Селектор?
- Каков самый быстрый способ выбора элементов-потомков в jQuery?
- Фильтр jquery имеет +
- Установите опцию выбора «selected», по значению
jQuery нет, но есть возможность назначить переменные в вашем выражении, а затем использовать повторное использование этих в последующих выражениях. Итак, кеширование вашего примера …
if ((cached = $("#navbar .heading")).text() > "") { cached.hide(); }
Даунсайд делает код немного более сложным и сложным.
Всегда кешируйте свои выборы!
Расточительно постоянно переводить $( selector )
снова и снова с помощью того же селектора.
Или почти всегда … Обычно вы должны хранить кешированную копию объекта jQuery в локальной переменной, если только вы не ожидаете, что она изменится или вам понадобится только один раз.
var element = $("#someid"); element.click( function() { // no need to re-select #someid since we cached it element.hide(); });
Это не столько вопрос «не так ли?», Но «не так ли?», И нет, это невозможно – вы могли бы добавить дополнительные сопоставимые элементы в DOM с тех пор, как запрос был последним. Это сделало бы кэшированный результат устаревшим, и у jQuery не было бы (разумного) способа сказать, кроме повторения запроса.
Например:
$('#someid .someclass').show(); $('#someid').append('New!'); $('#someid .someclass').hide();
В этом примере вновь добавленный элемент не будет скрыт, если будет какое-либо кэширование запроса – он скроет только те элементы, которые были обнаружены ранее.
Я просто сделал метод решения этой проблемы:
var cache = {}; function $$(s) { if (cache.hasOwnProperty(s)) { return $(cache[s]); } var e = $(s); if(e.length > 0) { return $(cache[s] = e); } }
И он работает следующим образом:
$$('div').each(function(){ ... });
Результаты являются точными, насколько я могу судить, основываясь на этой простой проверке:
console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);
NB, он нарушит вашу реализацию MooTools или любую другую библиотеку, которая использует нотацию $$
.
Я не думаю, что это так (хотя я не хочу читать через три с половиной тысячи строк JavaScript на данный момент, чтобы точно узнать).
Однако то, что вы делаете, не требует нескольких селекторов – это должно работать:
$("#navbar .heading:not(:empty)").hide();
Как и ваш подход $$, я создал функцию (с тем же именем), которая использует шаблон запоминания для сохранения глобального очистителя и также учитывает второй параметр контекста … например $$ (“. Class”, “#context” ). Это необходимо, если вы используете цепочку find (), которая появляется после возврата $$; поэтому он не будет кэшироваться в одиночку, если вы сначала не кэшируете контекстный объект. Я также добавил параметр boolean в конец (2-й или 3-й параметр в зависимости от того, используете ли вы контекст), чтобы заставить его вернуться в DOM.
Код:
function $$(a, b, c){ var key; if(c){ key = a + "," + b; if(!this.hasOwnProperty(key) || c){ this[key] = $(a, b); } } else if(b){ if(typeof b == "boolean"){ key = a; if(!this.hasOwnProperty(key) || b){ this[key] = $(a); } } else{ key = a + "," + b; this[key] = $(a, b); } } else{ key = a; if(!this.hasOwnProperty(key)){ this[key] = $(a); } } return this[key]; }
Применение:
ab
ab
Я не верю, что jquery выполняет кэширование селекторов, вместо этого опираясь на xpath / javascript под ним. что, как говорится, есть ряд оптимизаций, которые вы можете использовать в своих селекторах. вот несколько статей, которые охватывают некоторые основы:
- Оптимизация производительности селектора jQuery
- Анализ эффективности селекторов
Этот $$ () работает отлично – должен возвращать действительный объект jQuery в любом случае никогда не определяемый.
Будьте осторожны! Он должен / не может с селекторами, которые могут динамически меняться, например. путем добавления узлов, соответствующих селектору, или с использованием псевдоclassов.
function $$(selector) { return cache.hasOwnProperty(selector) ? cache[selector] : cache[selector] = $(selector); };
И $$ может быть любым именем funciton, конечно.
Джон Ресиг в своем интервью JQuery Internals в jQuery Camp 2008 упоминает о некоторых браузерах, поддерживающих события, которые запускаются при изменении DOM. В таких случаях результаты Selctor могут быть кэшированы.
Там есть хороший плагин, называемый jQache, который делает именно это. После установки плагина я обычно делаю это:
var $$ = $ .q;
И тогда просто
$$ (“# navbar .heading”). hide ();
Лучшая часть всего этого заключается в том, что вы можете также очистить свой кеш при необходимости, если вы делаете динамический материал, например:
$$ (“# navbar .heading”, true) .hide (); // сбрасывает кеш и скрывает новый (только что найденный) #navbar .heading
А также
. $$ ясно (); // Полностью очищает кеш
jQuery Sizzle автоматически кэширует последние функции, созданные из селекторов, чтобы найти элементы DOM. Однако сами элементы не кэшируются.
Кроме того, Sizzle хранит кэш наиболее недавно скомпилированных функций. Кэш имеет максимальный размер (который может быть изменен, но имеет значение по умолчанию), поэтому вы не получаете ошибок при отсутствии памяти при использовании множества разных селекторов.
Сегодня jsPerf работает, но в этой статье предполагается, что производительность, получаемая от кеширования селекторов jQuery, будет минимальной.
Это может быть просто к кешированию браузера. Проверенный селектор был только одним идентификатором. Необходимо провести дополнительные тесты для более сложных селекторов и различных структур страниц …
$ .selectorCache () полезен:
https://gist.github.com/jduhls/ceb7c5fdf2ae1fd2d613e1bab160e296
Gist embed:
Проверьте, помогает ли это https://plugins.jquery.com/cache/
Это произошло в рамках нашего регулярного проекта