【问题标题】:Javascript performance: Caching vs No Caching - weird resultsJavascript 性能:缓存与无缓存 - 奇怪的结果
【发布时间】:2012-09-07 17:10:24
【问题描述】:

我正在尝试优化一些遍历和隐藏/显示一些无序列表的基本 jquery 脚本。

这是 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");

谁能解释我做错了什么以及为什么缓存的版本似乎更慢?

【问题讨论】:

  • 我大胆猜测,您从缓存版本中获得的好处不会超过缓存数据的开销,因此收集和存储所有数据需要更多的总时间缓存目的而不是检索和返回非缓存版本所需的特定数据。

标签: jquery dom performance


【解决方案1】:

简短回答:选择器实际上非常快,但 find 慢得要命。您的缓存版本引入了多个 find 调用 - 这很慢。

稍微长一点的答案:如果你继续按原样重复使用它,你只会从缓存 jQuery 集合中真正受益。看看这个缓存版本明显跑得更快的测试用例:http://jsperf.com/cachingjq

【讨论】:

  • 这个。在我看来,如果你经常使用find,你很有可能需要重新评估你的选择器
  • 即使问题得到了解答,如果 find 是不可能的,那么改进原始代码的简单替代方法是什么?
【解决方案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");

【讨论】:

  • 谢谢,巧妙地使用逗号分隔的选择器来定义上下文。没想到。
  • 似乎确实更快。 2-3%
【解决方案3】:

find() 是“慢得要命”还是实际上快得要命,这是有争议的。您的性能问题可能取决于您使用的 jQuery 版本或 DOM 的结构。

请参阅此处以了解find() 性能的另一面: jQuery selector performance, http://seesparkbox.com/foundry/jquery_selector_performance_testing

基准测试:Find() Vs Selector

【讨论】:

  • 这篇文章很有启发性。我想知道 jQuery 版本是否对此有影响。 (无论您使用的是旧版本还是最新版本..)
【解决方案4】:

缓存你实际要处理的元素,在你的例子中是“li”元素。

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

由于对 li 元素的额外和冗余搜索,您的“优化”缓存版本实际上优化程度较低。

【讨论】:

  • 添加一些上下文并帮助查询?
  • @GeorgeKatsanos 我想对于上下文,您可以在我的示例中将变量更改为 menuItems。在帮助查询方面,缓存父项会迫使您在每个后续语句中重复 li 选择器,这不是对“未优化”示例的优化。当我希望优化选择器 $('?') 时,我会首先尝试最小化选择器的 $('?').length,从最高级别开始,然后逐步向下。
猜你喜欢
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多