Skip to content

ui.widget: don't trigger 'remove' event for non-widget elements #1183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

amakhrov
Copy link

An updated version of the previous pull request

ui.widget overrides the $.cleanData method to also call .triggerHandler( "remove" ) method. According to Chrome's profiler, triggerHandler is a relatively slow method.

When element is being removed with $(elem).remove(), $.cleanData is called for each descendant element - and there can be thousands of those elements!

This is an attempt to only execute triggerHandler( "remove" ) for elements that are jQueryUI Widgets and skip that for all other elements.

Benchmark - pure jQuery vs jQueryUI vs fixed jQueryUI

@scottgonzalez
Copy link
Member

@rwaldron Can we get a ruling on storing a boolean directly on a DOMElement?

@scottgonzalez
Copy link
Member

If I'm reading that benchmark right, you used a single element for the entirety of the body? This is a horrible representation of what happens in real pages.

@amakhrov
Copy link
Author

You're right.
But why do you think it's relevant in the context of this issue?

When an element (on a real page) is removed, jquery gets all its descendant elements (with getElementsByTagName("*")) and then passes this list to .cleanData.
The performance issue I came across is related to the fact the slow piece of code inside .cleanData is called for every single element of this list.

This is the updated benchmark - http://jsperf.com/jquery-ui-remove-elements/2
Here the removed element has 1000 child nodes, which is closer to real life and to what I have in my app.

Does it make sense to you?

@scottgonzalez
Copy link
Member

But why do you think it's relevant in the context of this issue?

Because your first benchmark shows that this takes less than 1ms in the browsers you tested. That's not a bottleneck.

The performance issue I came across is related to the fact the slow piece of code inside .cleanData is called for every single element of this list.

Is your new benchmark showing the actual problem you're facing? The benchmark shows that this is running in about 13ms for 1000 elements being removed. That's about the speed of setTimeout(function() {}, 0) in many browsers.

@amakhrov
Copy link
Author

Ok, I see you point now.

In my app I render a list of 2000+ items, each of which has some markup inside, so total nodes are 16000+
the benchmark with 16000 elements is here: http://jsperf.com/jquery-ui-remove-elements/2
with the original jquery ui it takes me significant time to remove it.

@scottgonzalez
Copy link
Member

This was fixed by #1291.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants