【问题标题】:How can jQuery's click() function be so much faster than addEventListener()?jQuery 的 click() 函数怎么会比 addEventListener() 快这么多?
【发布时间】:2012-11-04 16:03:24
【问题描述】:

我相信我们都见过site for vanilla-js(最快的 JavaScript 框架);D 我只是好奇,在为点击添加事件处理程序方面,纯 JavaScript 究竟比 jQuery 快多少。所以我前往 jsPerf 进行测试,我是 quite surprised by the results

jQuery 比普通 JavaScript 的性能高出 2500%

我的测试代码:

//jQuery
$('#test').click(function(){
  console.log('hi');
});

//Plain JavaScript
document.getElementById('test').addEventListener('click', function(){
  console.log('hi');
});

我只是不明白这是怎么发生的,因为看起来 jQuery 最终将不得不使用与普通 JavaScript 完全相同的函数。 谁能解释一下为什么会发生这种情况?

【问题讨论】:

  • 我想知道您在这里看到的是否是在 jsperf 中一遍又一遍地运行相同代码的工件。 jQuery 可能只调用一次 addEventListener(),然后将所有其他 .click() 处理程序链接到该调用上,而普通 JS 每次都会调用 addEventListener() - jsPerf 如何测量事物的人工制品 - 不是典型的真实测量世界使用情况。

标签: javascript jquery event-handling jquery-events


【解决方案1】:

正如您在 jQuery.event.add 的这个 sn-p 中看到的,它只创建一次 eventHandle。
查看更多:http://james.padolsey.com/jquery/#v=1.7.2&fn=jQuery.event.add

 // Init the element's event structure and main handler, if this is the first
events = elemData.events;
if (!events) {
    elemData.events = events = {};
}
eventHandle = elemData.handle;
if (!eventHandle) {
    elemData.handle = eventHandle = function (e) {
        // Discard the second event of a jQuery.event.trigger() and
        // when an event is called after a page has unloaded
        return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined;
    };
    // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
    eventHandle.elem = elem;
}

这里我们有 addEventListener:

    // Init the event handler queue if we're the first
    handlers = events[type];
    if (!handlers) {
        handlers = events[type] = [];
        handlers.delegateCount = 0;

        // Only use addEventListener/attachEvent if the special events handler returns false
        if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
            // Bind the global event handler to the element
            if (elem.addEventListener) {
                elem.addEventListener(type, eventHandle, false);

            } else if (elem.attachEvent) {
                elem.attachEvent("on" + type, eventHandle);
            }
        }
    }

【讨论】:

【解决方案2】:

我认为这是因为 jQuery 在内部实际上只需要调用addEventListener() 一次,用于它自己的内部处理程序。设置完成后,只需将您的回调添加到一个简单的列表中。因此,大多数对.click() 的调用只是做一些记账和.push()(或类似的东西)。

【讨论】:

  • 我认为可能会发生这样的事情,但是当我查看代码时,我不太清楚在哪里。你知道这是在哪里发生的吗?
  • @Aust 让我看看能不能找到确凿的证据。
猜你喜欢
  • 2011-06-02
  • 2014-01-11
  • 2011-11-27
  • 2020-12-19
  • 2012-03-18
  • 2014-05-09
  • 2016-08-17
  • 2012-05-18
  • 1970-01-01
相关资源
最近更新 更多