绑定父元素与元素直接相比有优缺点吗?
为了更好地理解jQuery性能,我遇到了以下问题。 考虑将click事件绑定到列表中的项目的两个大致相同的解决方案:
清单项目:
请注意,有两个完整列表(除了ID)。 现在,考虑以下jQuery来绑定item
s中每个锚点的客户端事件:
$('#items').on('click', '.item a', function(e) { console.log("### Items click"); }); $('#items2 .item a').on('click', function(e) { console.log("### Items2 click"); });
这实现了相同的结果,因为单击列表中的项目将输出它们各自的消息。
观察绑定的事件,在第一种情况下,click事件被绑定到#items
容器,没有事件绑定到子#items
。 但是,在第二种情况下, 没有将 click事件绑定到父#items2
,但每个子元素都有一个click事件。
现在,我的问题是: 一个明显优于另一个吗? 天真,我会认为第一种情况更可取,但缺乏对jQuery内部的了解,很可能这两者在内幕时是相同的。
我准备了一个小提琴演示两个案例。 观察jQuery为元素构建的事件,是我推导出上述假设的地方(您可以在Web浏览器的控制台中看到输出)。
除非你正在处理大量的元素,否则两种方式都无关紧要。 问题是你何时需要提高效率:在绑定时或触发时?
免责声明:我并不认为任何这些测试都是完美的。 另外,我只在Chrome中测试过。
约束时间
我不知道答案,所以我决定尝试测试一切。 首先,我假设使用委托会更快地进行绑定(它只需绑定一次而不是X次)。 这似乎是正确的。
http://jsperf.com/on-delegate-vs-not-bind-only
不要委托:慢100%
触发时间
接下来,我认为不使用委托可能实际上更快地触发事件,因为不需要DOM移动来检查事件触发。 无论出于何种原因,我对此不正确:
http://jsperf.com/on-delegate-vs-not-trigger-pls
不委托:慢60%
(最初的.trigger
是为了防止jQuery缓存委托事件,我相信它.trigger
。这会影响测试)。
仅触发一个项目
然后,我认为不使用委托会更快地触发一个特定项目上的事件。 这也错了:
http://jsperf.com/on-delegate-vs-not-trigger-one
不委托:慢80%
即使它不是最后一个兄弟姐妹,也是早期的兄弟姐妹之一,这是如此:
http://jsperf.com/on-delegate-vs-not-trigger-one-eq2
深度嵌套
最后,我认为委托完成的很多工作都必须是DOM树解析。 这意味着在深度嵌套的DOM中使用委托并绑定到一个非常古老的祖先并且触发比在深层嵌套的项本身上绑定和触发花费更长的时间。
这最终certificate是正确的:
http://jsperf.com/on-delegate-vs-not-deep-nesting
代表:慢90%
结论
我不能在这里得出任何具有重大意义的结论,但是如果你有大量的DOM可以使用,特别是如果它是深度嵌套的,你可能会看一下使用委托进行绑定而不是直接绑定。
如果有的话,这些例子教会了我(好吧,无论如何都强化了)你应该尝试让委托元素尽可能接近将触发事件的后代。
这是优化的问题。 让我解释:
$('#items2 .item a').on('click', function(e) { console.log("### Items2 click"); });
使用上面的代码,每个锚都有自己的事件处理程序。 这是浪费内存,因为只有一个处理程序可以执行相同的操作。
$('#items').on('click', '.item a', function(e) { console.log("### Items click"); });
另外,对于第二个代码,如果在绑定后向#items
添加更多锚点,则无需添加新的事件处理程序。 父元素#items
已经覆盖了它们。