2012-09-14 5 views
0

Я пытаюсь оптимизировать некоторый базовый сценарий jquery, который пересекает и скрывает/показывает некоторые неупорядоченные списки.Javascript performance: Caching vs No Caching - weird results

Вот TestCase в JSPerf: http://jsperf.com/caching-vs-no-caching

Я запустить тест в двух браузерах: Chrome и IE7/IE8 и удивительно кэшируются случай медленнее - по чуть-чуть, но до сих пор.

неоптимизированная версия:

(function($) { 
    $.fn.menuManipulation = function() { 
    this.parents().show(); 
    }; 
})(jQuery); 

$('.menu-vertical li.selected').menuManipulation(); 
$(".menu-vertical li.selected > ul.static").show(); 
$('li.static').has('ul').addClass("with-child"); 

и кэшируются один:

(function($) { 
    $.fn.menuManipulation = function() { 
    this.parents().show(); 
    }; 
})(jQuery); 

var menu = $('.menu-vertical'); 
menu.find('li.selected').menuManipulation(); 
menu.find('li.selected > ul.static').show(); 
menu.find('li.static').has('ul').addClass("with-child"); 

Может кто-нибудь объяснить, что я делаю неправильно и почему кэшированные версии кажутся медленнее?

+0

Я бы рискнул предположить, что преимущество, которое вы получаете из кешированной версии, не перевешивает накладные расходы на кеширование данных, поэтому требуется больше времени для сбора и хранения всех данных для целей кеширования, чем это делает для получения и возврата определенных данных, которые вы хотите использовать для не кэшированной версии. – taz

ответ

5

Короткий ответ: Селекторы на самом деле довольно быстр, но find медленно, как ад. Ваша кэшированная версия ввела несколько звонков find - это то, что медленно.

Немного более длинный ответ: вы действительно получаете выгоду от кеширования коллекции jQuery, если вы продолжаете использовать ее как есть. Посмотрите на этот тест случае, когда в кэше версия явно работает быстрее: http://jsperf.com/cachingjq

+1

Это. На мой взгляд, если вы используете 'find' много, есть хорошая вероятность, что вам нужно переоценить свои селекторы. – BLSully

+0

Даже если на вопрос будет дан ответ, что было бы хорошей простой альтернативой для улучшения исходного кода, если find вне вопроса? –

+0

@GeorgeKatsanos: см. Мой ответ с примером кода – BLSully

2

Джордж,

Попробуйте это в «кэшированных» случае и увидеть, что разница в производительности:

(function($) { 
    $.fn.menuManipulation = function() { 
     this.parents().show(); 
    }; 
})(jQuery); 

var menu = $('.menu-vertical'); 
$('li.selected', menu).menuManipulation(); 
$('li.selected > ul.static', menu).show(); 
$('li.static', menu).has('ul').addClass("with-child"); 
+0

спасибо, умное использование селекторов, разделенных запятыми, для определения контекста. Не пришло в голову. –

+0

кажется скорее быстрым. На 2-3% –

1

Это спорно, является ли find() является «медленным, как ад», или Infact быстро, как ад. Проблемы с производительностью могут зависеть от версии jQuery, используемой вами, или от структуры вашего DOM.

Смотрите здесь для другой стороны аргумента для find() производительности: jQuery selector performance, http://seesparkbox.com/foundry/jquery_selector_performance_testing

Benchmark тест: Find() Vs Selector

+0

Эта статья является просветительной. Интересно, влияет ли на версию jQuery.(используете ли вы устаревшую версию или последнюю версию ..) –

1

Cache элементы вашей фактически будет работать, в вашем случае " li 'элементов.

var menu = $('.menu-vertical li'); 
menu.filter('.selected').children('ul.static').show().end().menuManipulation(); 
menu.filter('.static').has('ul').addClass("with-child"); 

Ваша «оптимизированная» версия кеша фактически менее оптимизирована из-за дополнительного и избыточного поиска элементов li.

+0

, чтобы добавить контекст и помочь в запросе? –

+0

@GeorgeKatsanos Я полагаю, что для контекста вы можете изменить переменную на menuItems в моем примере. С точки зрения помощи в запросе кэширование родительских сил вам нужно повторить селектор li в каждом из последующих операторов, что не является оптимизацией по вашему «неоптимизированному» примеру. Когда я пытаюсь оптимизировать селектор, $ ('?'), Я стараюсь сначала минимизировать длину селекторов $ ('?'), Начиная с самого высокого уровня и уменьшая производительность. – Rob

+0

Спасибо, теперь становится понятнее. –