大型DOM树减少了jQuery点击事件

时间:2013-04-26 20:01:36

标签: jquery performance events optimization

解决了问题!

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

<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中的元素数量有关。而不是图像本身。

尝试解决方案

正如您在上面的示例代码中所看到的,我已经尝试实现过去几天我能找到的最佳解决方案。也就是说,将.inventory_item的集合包装在一个可识别ID的#inventory_index元素中,以便为jQuery提供一个关于它应该在哪里查看的提示。

另外,创建一个javascript对象来尝试从DOM搜索中获得更多时间(但是,老实说,我不确定完全它是如何工作的,或者它是否有帮助在所有)。

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

当前最佳创意

截至目前,我想象的唯一方法就是通过将较少的结果加​​载到#inventory_index中来简单地减少DOM树中的元素数量。这是一个选项,但我真的希望能够将数百个.inventory_item加载到索引中,而不是数千个{{1}}。

奖金

奇怪的是,mouseenter和mouseleave事件瞬间爆发。你可以在这里看到类似的问题:

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

1 个答案:

答案 0 :(得分:13)

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

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

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

一些解释:

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