问题 jQuery性能:$('#selector')。live()vs手动绑定(当使用ajax请求时)


处理异步加载的内容时,从性能角度来看,它们之间存在任何差异:

// .live()
$('#mybutton').live('click', function(e){ doSomething(); });

并在每次加载内容后手动bind()我们需要的事件:

// manual bind every time
$.ajax({
    url: url,
    success: function(data){
        mycontainer.html(data); // data contains #mybutton
        $('#mybutton').click(function(e){ doSomething(); });  
    }
});


9249
2017-11-12 11:00


起源

artzstudio.com/2009/04/jquery-performance-rules - Mike Grace


答案:


有不同的成本,让我们来看看它们:

$('#mybutton').live('click', function(e){ doSomething(); });

这里有2个主要成本:

  • #mybutton 选择器需要立即运行(结果被抛弃,我们只是想要选择器...我们绑定到 document)。在这种情况下它是一个 #id 选择 所以这是一个非常低的成本......在其他情况下,它并不便宜而且非常浪费(例如 [attr=something])。
  • 一切 click 泡沫达到 document 现在必须根据此选择器进行检查,每次点击评估费用,这会随着您期望的点击次数而变化。

现在让我们看看另一种方法:

$('#mybutton').click(function(e){ doSomething(); });  

这里还有两个主要成本:

  • #mybutton 选择器运行,但每个ajax请求只运行一次。但是,我们并没有浪费它,我们正在使用结果。
  • click handler绑定到一个实际的元素,而不是 document,所以有一个约束成本  它运行的时间,而不是一次

但是,没有每次点击成本,选择器调用本身也没有浪费...所以整体上更好, 因为你正在使用ID,在其他情况下不是这样。


在您的情况下,因为您正在处理ID(并保证单个元素), 这要便宜得多

$('#mybutton').click(function(e){ doSomething(); }); 

在其他情况下,你绑定数百个元素, .live() 但是,他是明显的赢家 .delegate() 会更好。


13
2017-11-12 11:05



@nemesis:@Nick意味着 document object,页面上所有元素的容器。 live 事件绑定在那里,因此无论事件发生在页面上,它们都可以捕获事件。 - Andy E
@Simon - 你不能阻止它冒泡,而不是 .live(), 那是 怎么样  .live() 首先得到事件...如果你停止冒泡(这意味着 另一个 绑定), .live() 处理程序不起作用。 - Nick Craver♦
@Nick - 我的意思是一直冒泡到顶部 - 你可以给它上下文,这样它就不会到达root。至少那是我读它的方式。对困惑感到抱歉。 - Simon
@Simon - 对......这是答案底部的评论 .delegate() 是 总是 更好(它使用 .live() 在下面,有一个上下文...和 仍然 不必要地运行选择器)。 - Nick Craver♦
@Nick啊,没见过那一个。注意它合理的新,所以将不得不再次点击文档:)。谢谢你的指针。 - Simon


可能有点,但我不担心。给我的 .live() 方法看起来更容易维护,所以我会用它。只要没有什么是痛苦的慢,就不必担心JavaScript中的性能。


1
2017-11-12 11:04



我不同意。我正在建立的应用程序密集使用淡入淡出,动画,工具提示,画廊和类似的东西所以我想确保一切尽可能顺利加载。如果代码以良好的方式组织,那么保持代码并不困难。我将把所有内容都包装在一个可以在每个案例中重用的函数中。 - nemesisdesign
好的,只要你仔细考虑了价值。在完全不必要的情况下,许多人对优化进行了大惊小怪,这就是我所建议的。 - Nathan MacInnes
是的,我同意你的意见,在简单的情况下,试图节省200毫秒是浪费时间。 - nemesisdesign


从成功函数的外观来看,您附加了一个事件,因为该元素现在可以在您的html中使用了吗?是这样吗?

如果是这种情况,那么如果通过点击调用的函数始终相同,那么您可以使用“实时”。 Live允许您绑定到尚不存在的事件。所以你甚至可以在你的document.ready之前把它放进去。然后,当ajax更新主文档时,该事件应始终有效。您不需要每次都分配它。

因此,每次从ajax调用返回时,您都可以获得不必执行某些操作的性能优势,您可以在不依赖document.ready的情况下进行设置,并确保其正常工作。

HTH。


1
2017-11-12 11:19