【问题标题】:Large DOM Tree Slowing Down jQuery Click Events大型 DOM 树减慢 jQuery 点击事件
【发布时间】:2013-04-21 02:14:10
【问题描述】:

问题解决了!

Dhoelzgen 和 Matthew Blancarte 根据接受的答案解决了这个问题(特定于我的配置)。问题的关键在于,当我应该使用 jQuery 的 on 方法来委托事件处理时,我将“点击”事件绑定到 all .inventory_item 元素,如下所示:

<head>
    <script>
        $(document).ready(function(){

            $('#inventory_index').on('click', '.inventory_item', function(){
                alert('Click event fired!');
            });

        });
    </script>
</head>

使用这种技术,我大大大大提高了我的应用程序的响应能力。

继续阅读所有细节...

概述

我正在开发一个在“单页”中运行的库存应用程序(例如 www.myapp.com/app.php),并使用 jQuery 执行 XHR 以将各种内容加载到 DIV 中。

我正在使用 jQuery 1.9.1 和 jQuery UI 1.8(因为我必须出于遗留原因)。

问题:缓慢的点击事件

我遇到的问题是随着 DOM 树变大,点击事件变得越来越慢。当搜索返回约 1000 个项目时,当前延迟约为 2 秒。

以下是 jQuery 示例:

<head>
    <script>
        $(document).ready(function(){
            var inventory_item = $('#inventory_index.inventory_item');

            inventory_item.on('click', function(){
                alert('Click event fired!');
            });
        });
    </script>
</head>

还有 HTML:

<div id="inventory_index">
    <div class="inventory_item">Inventory Item 0 <img src="inventory_item_0.jpg"></div>
    <!-- 999 Iterations -->
    <div class="inventory_item">Inventory Item 1000 <img src="inventory_item_1000.jpg"></div>
</div>

起初我认为这是因为每个 .inventory_item 中存在图像,但在实现延迟加载后,我发现问题更多地与 DOM 中的元素数量有关,而不是与 DOM 中的元素数量有关对图像本身进行了处理。

尝试的解决方案

正如您在上面的示例代码中看到的那样,我已经尝试实施过去几天我能找到的最佳解决方案。即,将 .inventory_item 的集合包装在一个可识别的 #inventory_index 元素中,以向 jQuery 提示它应该查找的位置。

此外,创建一个 javascript 对象来尝试减少 DOM 搜索的更多时间(虽然,老实说,我不确定 究竟它是如何工作的,或者它是否有帮助完全)。

有没有其他人遇到过这个问题并有任何可以分享的解决方案或建议?

当前最佳创意

到目前为止,我认为可以解决此问题的唯一方法是通过将更少的结果加​​载到#inventory_index 中来简单地减少 DOM 树中的元素数量。这是一个选项,但我真的很想保留将数百个(如果不是数千个).inventory_item 加载到索引中的能力。

奖金

奇怪的是,mouseenter 和 mouseleave 事件会立即触发。您可以在这里看到类似的问题:

jQuery delegate performance on the click event on large lists - slows down if you dynamically add more elements?

【问题讨论】:

  • 您应该在将事件处理程序添加到#inventory_index 时尝试绑定它。事件委托很慢,您肯定会看到直接绑定的更好性能。
  • 嗨@Vega,所以你的意思是我应该在我的PHP/MySQL结果的while循环中“执行”绑定?另外,我读过关于委托绑定的相反内容;他们不应该更快吗?
  • 只是一个小问题,但除非我今天早上真的睡过头了,否则你可能使用的是 jQuery 1.9.1。是的,我知道:迂腐!但是,这毕竟是互联网。
  • @AJB 您是否使用 AJAX 来添加 inventory_item?如果是这样,在将结果附加到#inventory_index 时,将处理程序绑定在success 回调中。
  • 在实施类似系统之前,我做了一些功课。我相信你刚刚救了我一大群头痛的猫。很好的问题和很好的答案。谢谢!

标签: jquery performance events optimization


【解决方案1】:

如何使用 jQuery 的 on method 来附加这样的事件处理程序:

$('#inventory_index').on('click', '.inventory_item', ...)

这样,您只需添加一个事件处理程序,而不是为每个库存项目添加一个。没有测试,只是偶然发现你添加了很多事件监听器。

一些解释:

如果您使用$('#inventory_index .inventory_item') 作为选择器,您最终会为每个库存项目绑定一个事件处理程序,这是一个问题,特别是如果您有很多库存项目。另一方面,上面的#inventory_index 选择器只是将单个事件处理程序添加到用作包装器的元素中,它负责处理对第二个选择器过滤的元素的所有点击,这是第二个参数.inventory_itemon 方法调用。

【讨论】:

  • 嗨@dhoelzgen,谢谢你的回答,但这基本上是我已经做过的......除非你能看到从 $('#inventory_index.库存物品')?
  • Jep,你有一个用于所有库存项目元素的选择器。另一个选择器仅适用于用作包装器的元素。
  • @AJB 是的,这个答案有很大的不同,尽管它没有得到彻底的解释。您需要委派事件(如本答案所示)。您当前正在使用直接绑定,这就是它变慢的原因。看到这个答案:stackoverflow.com/a/8111171/614152
  • 另外,查找解释直接和委托绑定的部分:api.jquery.com/on
  • 我在答案中添加了解释以使其更清楚
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多