最小化jQuery实例与创建更多实例的比较

9
我开始写一系列关于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");

查看测试结果(略有不同的场景)。jsperf minimize-jquery-object-creation 发现缓存片段比未缓存的片段更慢。

我试图理解为什么?


这就是为什么代码分析如此重要。 - Robert Harvey
1
可能 jQuery 的 .find() 比 DOM 搜索慢? - XCS
3个回答

3

我认为find()函数是导致速度变慢的原因。

只有当您需要多次引用或操作jQuery对象时,才需要将其缓存。如果您只是设置CSS属性,并且该属性在呈现页面的生命周期内不会更改,则没有必要定义缓存变量。


有趣的观点,我们需要更改测试,你有什么想法如何深入了解这个问题的根本原因吗? - adardesign
看起来这是正确的。.find() 过滤元素并检查是否有与选择器匹配的子元素,而 $('.className') 使用本地的 document.getElementsByClassName(如果存在的话)。 - scurker
@adardesign 是的,看起来是这样。如果sizzle找到一个类并且传递了上下文,则使用context.getElementsByClassName - scurker
1
@adardesign: $(".element1",appRoot) 最终与 appRoot.find(".element1"); 完全相同。 - user113716
请参见 http://jsperf.com/minimize-jquery-object-creation/11,其中结果略有不同,使得这个问题变得更加复杂 :) - adardesign
显示剩余2条评论

2
我认为在“创建更多的jQuery对象”中,原因是jQuery可以直接使用最近的API。
document.getElementsByClassName("classvalue")

在另一种情况下,使用“较少的jquery”,您需要始终验证找到的元素是否位于#appRoot下,这需要更多的时间。这里是另一个测试,使用document作为appRoot,在第二次运行时似乎缩小了差距:http://jsperf.com/minimize-jquery-object-creation/6

1
我也有同样的疑问,不过可以使用appRoot.getElementsByClassName("element1")来调用原生函数,并返回appRoot的子元素。 - jfriend00

2
你需要考虑到你的测试包含少于10个div或其他html元素。像第一个示例中那样编写代码的原因是为了使选择器更快,但代价是增加了额外的方法调用。通常情况下,选择器应该比另一个更昂贵得多,因此收益将大于损失,但是对于这么小的DOM来说,无论如何编写它,选择器都会非常便宜。
人们经常犯错,没有记住更复杂和更大的DOM将改变代码的瓶颈。我认为jsperf应该有某种警告。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接