Search and Top Navigation
#15043 closed bug (fixed)
Opened September 08, 2016 12:39PM UTC
Closed September 13, 2016 07:16PM UTC
Last modified September 13, 2016 07:46PM UTC
Widget: Internal list of elements with classes can't be cleaned up
Reported by: | WickedDevils | Owned by: | arschmitz |
---|---|---|---|
Priority: | minor | Milestone: | 1.12.1 |
Component: | ui.widget | Version: | 1.12.0 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I used the code from site http://jqueryui.com/autocomplete/#combobox and noticed a significant performance issue on my page. My list has ~3000 options in the combobox. I noticed that most of the time it was stuck in the in the jquery js file within this set of code:
indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[i] === elem ) { return i; } } return -1; },`
Even though my list object was only expected to be ~3000 rows, it was actually significantly higher. Here is my stacktrace:
indexOf (jquery-1.12.4.js:644) hasDuplicate (jquery-1.12.4.js:1375) Sizzle.uniqueSort (jquery-1.12.4.js:1518) processClassString (jquery-ui.js:510) _classes (jquery-ui.js:523) _toggleClass (jquery-ui.js:549) _addClass (jquery-ui.js:537) refresh (jquery-ui.js:5249) (anonymous function) (jquery-ui.js:144) _suggest (jquery-ui.js:6100) (anonymous function) (jquery-ui.js:144) __response (jquery-ui.js:6043) (anonymous function) (jquery-ui.js:144) _superApply (jquery-ui.js:133) __response (jquery-ui.js:6229) (anonymous function) (jquery-ui.js:144) (anonymous function) (jquery-ui.js:6027) proxy (jquery-1.12.4.js:529) _source (combobox.html:108) (anonymous function) (jquery-ui.js:144) proxy (jquery-1.12.4.js:529) _search (jquery-ui.js:6019) (anonymous function) (jquery-ui.js:144) search (jquery-ui.js:6011) (anonymous function) (jquery-ui.js:144) (anonymous function) (jquery-ui.js:5992) handlerProxy (jquery-ui.js:621)
In processClassString it does line:
current = $( $.unique( current.get().concat( options.element.get() ) ) );
The current list is my 3000 or so rows initially, and then it adds the elements back into that list making it roughly 6000 rows. Depending on how the user is interacting with the page (clicking the dropdown icon multiple times, typing into the textbox for the filter and then deleting the text, etc), it will keep adding to itself. At one point I had almost 200,000 rows in my 'list' variable.
I was able to reproduce this by stepping through the code using Chrome developer tools on http://jqueryui.com/autocomplete/#combobox .
Attachments (0)
Change History (11)
Changed September 08, 2016 12:45PM UTC by comment:1
resolution: | → patcheswelcome |
---|---|
status: | new → closed |
Changed September 08, 2016 01:32PM UTC by comment:2
It's not the widget that is the problem. It is the code behind it that duplicates the data. Did you read what I said at all?
Changed September 08, 2016 02:32PM UTC by comment:3
Yes, I read what you wrote. I don't see how the code could get up to 200,000 elements from 3,000. It does one concatenation, and then removes the duplicates, so the max count should never be more than 6,000. But even that number should never be reached. Because you've said that there are many interactions involved, and each interaction is actually its own completely separate operation with a new list each time, I don't see the correlation. Your stack trace shows processClassString()
being called once and that doesn't provide any information about the number of elements.
Unless you can provide a concrete way for us to see that there is a problem, there's not much we can do.
Changed September 08, 2016 04:17PM UTC by comment:4
I created a video on how to reproduce the issue with the jquery autocomplete example. I have significantly more import options than what the example has.
Changed September 08, 2016 04:29PM UTC by comment:5
This is the chunk of code I have found so far where the ui-menu-items are added
// Don't refresh list items that are already adapted newItems = items.not( ".ui-menu-item, .ui-menu-divider" ); newWrappers = newItems.children() .not( ".ui-menu" ) .uniqueId() .attr( { tabIndex: -1, role: this._itemRole() } ); this._addClass( newItems, "ui-menu-item" ) ._addClass( newWrappers, "ui-menu-item-wrapper" );
I can see them adding to the list in newItems
Changed September 08, 2016 04:32PM UTC by comment:6
component: | ui.autocomplete → ui.widget |
---|---|
resolution: | patcheswelcome |
status: | closed → reopened |
summary: | JQuery autocomplete performance issue → Widget: Internal list of elements with classes can't be cleaned up |
version: | 1.11.3 → 1.12.0 |
Ok, now I see what's happening. The widget keeps track of the element that have classes applied, but in the case of autocomplete, the menu is constantly rebuilt, so the list grows with every render. Widgets need a way to signify that elements have been removed and should be taken out of the list.
Changed September 08, 2016 08:24PM UTC by comment:7
I reverted jquery UI JS to 1.9 and this problem does not exist. Somewhere between 1.9 and 1.12 it is not working correctly.
Changed September 08, 2016 08:29PM UTC by comment:8
That somewhere is 1.12.0, which is why I corrected the version field.
Changed September 13, 2016 07:16PM UTC by comment:9
_comment0: | Fixed in [https://github.com/jquery/jquery-ui/commit/89af4c292eaa5fc1c83437ca71085264dcbef34a 89af4c292eaa5fc1c83437ca71085264dcbef34a] → 1473795928474446 |
---|---|
milestone: | none → 1.12.1 |
resolution: | → fixed |
status: | reopened → closed |
Changed September 13, 2016 07:45PM UTC by comment:10
owner: | → arschmitz |
---|
In [changeset:"89af4c292eaa5fc1c83437ca71085264dcbef34a" 89af4c2]:
#!CommitTicketReference repository="" revision="89af4c292eaa5fc1c83437ca71085264dcbef34a" Widget: Untrack classes elements when they are removed from the DOM Fixes #15043 Closes gh-1744
Changed September 13, 2016 07:46PM UTC by comment:11
description: | I used the code from site http://jqueryui.com/autocomplete/#combobox and noticed a significant performance issue on my page. My list has ~3000 options in the combobox. I noticed that most of the time it was stuck in the in the jquery js file within this set of code: \ \ ` indexOf = function( list, elem ) { \ var i = 0, \ len = list.length; \ for ( ; i < len; i++ ) { \ if ( list[i] === elem ) { \ return i; \ } \ } \ return -1; \ },` \ \ Even though my list object was only expected to be ~3000 rows, it was actually significantly higher. Here is my stacktrace: \ \ `indexOf (jquery-1.12.4.js:644) \ hasDuplicate (jquery-1.12.4.js:1375) \ Sizzle.uniqueSort (jquery-1.12.4.js:1518) \ processClassString (jquery-ui.js:510) \ _classes (jquery-ui.js:523) \ _toggleClass (jquery-ui.js:549) \ _addClass (jquery-ui.js:537) \ refresh (jquery-ui.js:5249) \ (anonymous function) (jquery-ui.js:144) \ _suggest (jquery-ui.js:6100) \ (anonymous function) (jquery-ui.js:144) \ __response (jquery-ui.js:6043) \ (anonymous function) (jquery-ui.js:144) \ _superApply (jquery-ui.js:133) \ __response (jquery-ui.js:6229) \ (anonymous function) (jquery-ui.js:144) \ (anonymous function) (jquery-ui.js:6027) \ proxy (jquery-1.12.4.js:529) \ _source (combobox.html:108) \ (anonymous function) (jquery-ui.js:144) \ proxy (jquery-1.12.4.js:529) \ _search (jquery-ui.js:6019) \ (anonymous function) (jquery-ui.js:144) \ search (jquery-ui.js:6011) \ (anonymous function) (jquery-ui.js:144) \ (anonymous function) (jquery-ui.js:5992) \ handlerProxy (jquery-ui.js:621) \ ` \ \ In processClassString it does line: \ \ `current = $( $.unique( current.get().concat( options.element.get() ) ) );` \ \ The current list is my 3000 or so rows initially, and then it adds the elements back into that list making it roughly 6000 rows. Depending on how the user is interacting with the page (clicking the dropdown icon multiple times, typing into the textbox for the filter and then deleting the text, etc), it will keep adding to itself. At one point I had almost 200,000 rows in my 'list' variable. \ \ I was able to reproduce this by stepping through the code using Chrome developer tools on http://jqueryui.com/autocomplete/#combobox . → I used the code from site http://jqueryui.com/autocomplete/#combobox and noticed a significant performance issue on my page. My list has ~3000 options in the combobox. I noticed that most of the time it was stuck in the in the jquery js file within this set of code: \ {{{#!js \ indexOf = function( list, elem ) { \ var i = 0, \ len = list.length; \ for ( ; i < len; i++ ) { \ if ( list[i] === elem ) { \ return i; \ } \ } \ return -1; \ },` \ }}} \ Even though my list object was only expected to be ~3000 rows, it was actually significantly higher. Here is my stacktrace: \ \ {{{ \ indexOf (jquery-1.12.4.js:644) \ hasDuplicate (jquery-1.12.4.js:1375) \ Sizzle.uniqueSort (jquery-1.12.4.js:1518) \ processClassString (jquery-ui.js:510) \ _classes (jquery-ui.js:523) \ _toggleClass (jquery-ui.js:549) \ _addClass (jquery-ui.js:537) \ refresh (jquery-ui.js:5249) \ (anonymous function) (jquery-ui.js:144) \ _suggest (jquery-ui.js:6100) \ (anonymous function) (jquery-ui.js:144) \ __response (jquery-ui.js:6043) \ (anonymous function) (jquery-ui.js:144) \ _superApply (jquery-ui.js:133) \ __response (jquery-ui.js:6229) \ (anonymous function) (jquery-ui.js:144) \ (anonymous function) (jquery-ui.js:6027) \ proxy (jquery-1.12.4.js:529) \ _source (combobox.html:108) \ (anonymous function) (jquery-ui.js:144) \ proxy (jquery-1.12.4.js:529) \ _search (jquery-ui.js:6019) \ (anonymous function) (jquery-ui.js:144) \ search (jquery-ui.js:6011) \ (anonymous function) (jquery-ui.js:144) \ (anonymous function) (jquery-ui.js:5992) \ handlerProxy (jquery-ui.js:621) \ }}} \ \ In processClassString it does line: \ \ `current = $( $.unique( current.get().concat( options.element.get() ) ) );` \ \ The current list is my 3000 or so rows initially, and then it adds the elements back into that list making it roughly 6000 rows. Depending on how the user is interacting with the page (clicking the dropdown icon multiple times, typing into the textbox for the filter and then deleting the text, etc), it will keep adding to itself. At one point I had almost 200,000 rows in my 'list' variable. \ \ I was able to reproduce this by stepping through the code using Chrome developer tools on http://jqueryui.com/autocomplete/#combobox . |
---|
From the demo page: "This is not a supported or even complete widget."