#15043 closed bug (fixed)
Widget: Internal list of elements with classes can't be cleaned up
Reported by: | WickedDevils | Owned by: | Alexander Schmitz |
---|---|---|---|
Priority: | minor | Milestone: | 1.12.1 |
Component: | ui.widget | Version: | 1.12.0 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description (last modified by )
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 .
Change History (11)
comment:1 Changed 7 years ago by
Resolution: | → patcheswelcome |
---|---|
Status: | new → closed |
comment:2 Changed 7 years ago by
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?
comment:3 Changed 7 years ago by
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.
comment:4 Changed 7 years ago by
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.
comment:5 Changed 7 years ago by
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
comment:6 Changed 7 years ago by
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.
comment:7 Changed 7 years ago by
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.
comment:8 Changed 7 years ago by
That somewhere is 1.12.0, which is why I corrected the version field.
comment:9 Changed 7 years ago by
Milestone: | none → 1.12.1 |
---|---|
Resolution: | → fixed |
Status: | reopened → closed |
comment:11 Changed 7 years ago by
Description: | modified (diff) |
---|
From the demo page: "This is not a supported or even complete widget."