委托是最快的绑定方式吗?

时间:2013-04-16 18:41:23

标签: jquery performance

有人可以解释为什么委托似乎比别名绑定或on()更快。

这是一个测试用例:

jsPerf

$('p').on('click',$.noop); //80% slower

$('p').click($.noop); //84% slower

$(document).delegate("p", "click",$.noop); //fastest

检查jquery源,看起来像绑定任何事件之前,jquery检查委托。

这是正确的陈述还是还有其他什么?

3 个答案:

答案 0 :(得分:6)

你犯的错误是认为只有一个p元素。

我添加了另一个测试,只有console.log($('p').length);,它显示测试中有7 p可见,其可见性显然不限于您在准备代码中构建的HTML。

这意味着两个第一个函数必须再进行7次绑定。

答案 1 :(得分:5)

delegate()bind()都只是致电on()。以下是jQuery 1.9.0源代码的摘录:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

所以on()应该比其他两个函数稍快一些,因为它少了一个函数调用。无论绑定方式如何,处理程序的实际调用都应该是相同的。

但请确保您将苹果与苹果进行比较。如果为selectordelegate提供bind参数,则调用处理程序会更慢,因为它必须检查目标是否满足选择器。

您的基准测试结果的原因是

$("p").on('click',$.noop);

等同于:

$("p").each(function() {
    $(this).on('click', $.noop);
});

它必须找到所有匹配的元素并将处理程序绑定到它们。 delegate()调用只需要将处理程序绑定到一个元素(文档);而不是在绑定时找到所有元素,在事件发生时它会执行以下操作:

if ($(event.target).is("p")) { ... }

使用等同于on()的{​​{1}}将是:

delegate()

当您从像$(document).on('click', 'p', $.noop); 这样的大型元素委派时,每次单击文档中的任何位置时都会调用内部处理程序,如果超过document,则会浪费时间进行测试。这就是为什么你应该尝试将p中使用的元素的范围限制为包含你想要委托的所有动态元素的最小静态元素。

答案 2 :(得分:5)

委托只是更快,因为你不必查找任何元素,如果使用选择器而不是元素委托将是最慢的

<div>
<p>test</p>
</div>


$('p').on('click',$.noop);
$('p').click($.noop);
$('div').delegate("p", "click",$.noop);

http://jsperf.com/test-on-click-delegate/3