jQuery选择器与局部变量的性能表现

20

当我需要在函数的范围内多次访问jQuery选择器的结果时,是否建议仅运行一次选择器并将其分配给本地变量?

抱歉我在这里举的例子很陈旧,但我认为它说明了这个问题。那么,这段代码会更快吗:

var execute = function(){
    var element = $('.myElement');
    element.css('color','green');
    element.attr('title','My Element');
    element.click(function(){
        console.log('clicked');
    });
}
比这段代码更好:
var execute = function(){
    $('.myElement').css('color','green');
    $('.myElement').attr('title','My Element');
    $('.myElement').click(function(){
        console.log('clicked');
    });
}
如果没有区别,那么有人能解释一下为什么吗?jQuery会在选择元素后缓存它们,因此后续的选择器就不必再次搜索dom吗?

感谢大家的回答,我希望我能够接受它们全部。 - KodeKreachor
5个回答

21

复用选择器引用,也就是你第一个情况,确实更快。这里是我做的一个测试,作为证明:

http://jsperf.com/caching-jquery-selectors

后一种情况,重新定义你的选择器,被报告为慢了约35%。


很赞的测试,非常好,但是我有点困惑...红色条是否代表“局部变量”的例子,因为它的标签是这么写的?看起来花费的时间更久了? - KodeKreachor
是的,red是局部变量。这有点令人困惑,图表中越长越好。它代表每秒可以运行多少个操作。 - weotch
谢谢你介绍我那个网站。它太棒了! - tsherif
好的,谢谢你,我需要在这里加一个+2按钮,一个是为了你的回答,另一个是为了那个出色的性能网站 ;) - KodeKreachor
哈,太棒了!我注意到当我添加了额外的测试后,颜色改变了。绿色是新的红色;) - weotch
看我的答案。真正的缓存方法速度显著更快。 - Guido Bouman

9

别忘了这个:

var execute = function(){ 
    $('.myElement')
        .css('color','green')
        .attr('title','My Element')
        .click(function(){ 
            console.log('clicked'); 
        });
}

@weotch 太好了。我回答得不够快,所以取消了我的相同答案...但确实很好知道这是一个选择。weotch 能把这个加入他的速度测试吗? - ZZ-bb
1
这是jQuery所设想的解决方案,因为他们的大多数示例 tend to chain calls together like this。也许它不比保存在本地变量中更快,但肯定比多次选择更快,我认为它更加优雅。 - Neil
2
添加了那个测试。它看起来并列第一! - weotch
@weotch 谢谢。重复使用变量仅在第一次运行时比链接略快。在第二次运行时,链接明显更快。尽管如此,我也会给这个答案加1分。无需重复编写选择器。稍微慢一点的第一次运行是为优雅的代码付出的小代价... - ZZ-bb
酷,我在这个网站上看到了许多jQuery开发者抨击其他开发者的链式编程。我个人完全没有问题,但有些人倾向于认为这是不好的实践,这让我开始重新考虑是否这样做。不过,jQuery显然是为了优雅地处理链式编程而构建的。我应该忽略那些反对链式编程的人吗?也许这是另一个完全不同的问题。 - KodeKreachor

3

将引用存储在本地变量中比每次运行选择代码更快。这只是一个不必执行任何代码即可找到适当元素的问题,如果要多次使用jQuery查找结果,则我的经验法则是将其存储在变量中。


1

您实际上正在忘记真正的缓存方法。

jQuery的问题在于初始查找:$('.selector')非常耗时。但是,在此之后,将您的操作链接到它上面,或将其分配给变量并在变量上执行您的操作并不那么重要。您可以获得的主要性能提升是进一步缓存元素,不要在每次函数调用迭代中分配jQuery选择器。

var element = $('.myElement');
var execute = function(){
    element.css('color','green');
    element.attr('title','My Element');
    element.click(function(){
        console.log('clicked');
    });
}

这种方法比其他建议中最快的版本快了近一倍。
请参见http://jsperf.com/caching-jquery-selectors/17 注:如果您的DOM在其生命周期内发生更改,可以使用新的元素选择更新element变量。

1

这里的另一个选项是使用each而不是一遍又一遍地重复选择器及其相关工作和时间。

var execute = function(){
    $('.myElement').each(function() {
      var elem = $(this);
      elem.css('color','green');
      elem.attr('title','My Element');
      elem.click(function(){
        console.log('clicked');
      });
    });
}

1
如果你关心性能,那么为对象重复重新分配内存并通过反复执行 $(this) 来进行不必要的函数调用(尽管它们相当快)是不太理想的。 - T.J. Crowder
1
“区别在于attr函数。如果将其应用于集合,则仅影响集合中的第一个元素。”不,这只适用于获取。在设置时,它会将其设置为所有元素:http://api.jquery.com/attr/#attr2 - T.J. Crowder
@T.J.Crowder,我的错,我没有看方法的签名,我只是在阅读文档。 - tvanfosson
这是一种相当低效的方法。每次执行该函数时,您都会循环遍历选择器内的所有元素,并使用var elem = $(this)进行新分配,使整个过程变慢n倍。其中n =选择器中的元素数量 - Guido Bouman

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