Big DOM tree slows down jQuery Click Events

The problem is solved!

This problem (specific to my configuration) was solved by Dholzgen and Matthew Blancar in accordance with the accepted answer. The essence of the problem was that I attached the 'click' events to all the .inventory_item elements, when I had to use jQuery for the delegation method of event processing, for example:

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

Using this technique, I significantly increased the responsiveness of my application.

Continue reading for all the details ...

Overview

I am working on an inventory application that runs on a "one page" (for example, www.myapp.com/app.php) and uses jQuery to run XHR to load various content from and from the DIV.

I am using jQuery 1.9.1 and jQuery UI 1.8 (because I should for obsolete reasons).

Problem: Slow Click Events

The problem I am facing is that click events get slower and slower as the DOM tree grows. The delay is currently around 2 seconds when ~ 1000 items are returned from the search.

Here is a jQuery example:

 <head> <script> $(document).ready(function(){ var inventory_item = $('#inventory_index.inventory_item'); inventory_item.on('click', function(){ alert('Click event fired!'); }); }); </script> </head> 

And 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> 

At first I assumed that this was due to the images that are inside each of the .inventory_item , but after implementing lazy loading, I found that the problem is more related to the number of elements in the DOM than it is to the images themselves.

Attempt to solve

As you can see in the above code example, I already tried to implement the best solutions that I could find in the last couple of days. Namely, wrapping the .inventory_item collection in an ID-capable element #inventory_index to give jQuery a hint about where it should look.

And besides, creating a javascript object to try to save even more time on finding the DOM (although, to be honest, I'm not sure exactly how this works, or if it helps at all).

Does anyone else encounter this problem and have any solutions or recommendations that they can use?

Current best idea

As of now, the only way I imagined this could be solved is to simply reduce the number of elements in the DOM tree by loading less results in #inventory_index . This is an option, but I would really like to keep the ability to load hundreds, if not thousands .inventory_item into the index.

Bonus

Oddly enough, the mouseenter and mouseleave events fire instantly. You can see a similar problem:

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

+4
source share
1 answer

How about using the jQuery method to attach an event handler as follows:

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

Thus, you should add only one event handler, and not one for each inventory item. Did not check it, just stumbled on the fact that you are adding a lot of event listeners.

Some explanation:

If you use $('#inventory_index .inventory_item') as a selector, you end up binding one event handler to each inventory item, which is a problem, especially if you have a lot of them. On the other hand, the #inventory_index selector above simply adds one event handler to the element used as a wrapper, which is responsible for handling all clicks on the elements filtered by the second selector, which is the second argument of .inventory_item to the on method call.

+12
source

All Articles