Skip to main content

Search and Top Navigation

#15082 closed bug (fixed)

Opened October 18, 2016 01:35PM UTC

Closed April 19, 2017 04:54PM UTC

Last modified September 12, 2017 07:43PM UTC

jQuery Autocomplete Duplicate Remove event listener

Reported by: jGeek314 Owned by: scottgonzalez
Priority: minor Milestone: 1.12.2
Component: ui.autocomplete Version: 1.12.1
Keywords: Cc:
Blocked by: Blocking:
Description

While trying to determine what was slowing down my autocomplete text box, I noticed that every time the user types in the target text box the number of event listeners would go up. It looks like autocomplete (or the widget factory?) is adding duplicate "remove" events to the target. This can be reproduced by adding the following line to the default autocomplete example at https://jqueryui.com/autocomplete/ .

response: function (e, ui) {
        console.log( jQuery._data( $("#tags")[0], "events" ) );
      }

When looking at the results in chrome's tools I can see the number of event listeners go up every time the the user types in the target text box.


Object {remove: Array[3], keydown: Array[1], keypress: Array[1], input: Array[1]...
Object {remove: Array[5], keydown: Array[1], keypress: Array[1], input: Array[1]...
Object {remove: Array[7], keydown: Array[1], keypress: Array[1], input: Array[1]...
Object {remove: Array[9], keydown: Array[1], keypress: Array[1], input: Array[1]...

http://plnkr.co/edit/Jk2xg3ZjJ5jS5mgP1zHZ?p=preview is a demo of the remove events growing.

Attachments (0)
Change History (10)

Changed October 19, 2016 12:58AM UTC by vladimir-i comment:1

I have also encountered a significant slowdown of autocomplete after upgrading from 1.11 to 1.12.

It gets worse the more you use it, eventually slowing to a crawl.

Here's a demo: https://jsfiddle.net/Lm7xqs37/1/

It's a copy of the default example but with more autocomplete options and with delay set to 0 to make it easier to see the slowdown.

To reproduce: enter and delete a letter (e.g. 's') a number of times and see how it gets slower and slower.

Chrome CPU profiler result:

5725.9 ms88.63 %	6109.0 ms94.56 %	hasDuplicate	jquery-1.12.4.js:1340	
5724.9 ms88.62 %	6109.0 ms94.56 %	Sizzle.uniqueSort	jquery-1.12.4.js:1509	
5724.1 ms88.61 %	6108.2 ms94.55 %	add	jquery-1.12.4.js:3063	
5724.1 ms88.61 %	6108.2 ms94.55 %	_on	jquery-ui.js:573	
5724.1 ms88.61 %	6108.2 ms94.55 %	_classes	jquery-ui.js:503	
5724.1 ms88.61 %	6108.2 ms94.55 %	_toggleClass	jquery-ui.js:560	
3930.8 ms60.85 %	4198.2 ms64.99 %	_addClass	jquery-ui.js:556	
3930.8 ms60.85 %	4198.1 ms64.98 %	refresh	jquery-ui.js:5195	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	_suggest	jquery-ui.js:6092	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	__response	jquery-ui.js:6033	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	_superApply	jquery-ui.js:132	
3930.8 ms60.85 %	4198.1 ms64.98 %	__response	jquery-ui.js:6223	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:6021	
3930.8 ms60.85 %	4198.1 ms64.98 %	proxy	jquery-1.12.4.js:528	
3930.8 ms60.85 %	4198.1 ms64.98 %	source	jquery-ui.js:5951	
3930.8 ms60.85 %	4198.1 ms64.98 %	_search	jquery-ui.js:6010	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	search	jquery-ui.js:5993	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:136	
3930.8 ms60.85 %	4198.1 ms64.98 %	(anonymous function)	jquery-ui.js:5979	
3930.8 ms60.85 %	4198.1 ms64.98 %	handlerProxy)	query-ui.js:639

Chrome heap profiler shows that every time autocomplete search happens the old results div and li elements become a detached dom tree that can't get garbage collected.

Changed October 19, 2016 01:14AM UTC by vladimir-i comment:2

Thanks to jGeek314 for the workaround in 10050, it works great:

search: function(e,ui){
     //fix bug in jQuery.ui somewhere where menu.bindings just grows and grows
     autoComplete.data("ui-autocomplete").menu.bindings = $();
},

Changed April 19, 2017 04:54PM UTC by scottgonzalez comment:3

owner: → scottgonzalez
resolution: → fixed
status: newclosed

In [changeset:"ef2e9bab92ae898311baa295590cd487d9071319" ef2e9ba]:

#!CommitTicketReference repository="" revision="ef2e9bab92ae898311baa295590cd487d9071319"
Widget: Improve  event bindings for  options

Fixes #15078
Fixes #15082
Fixes #15095
Fixes #15136
Fixes #15152
Closes gh-1769

Changed April 19, 2017 04:56PM UTC by scottgonzalez comment:4

milestone: none1.12.2

Changed August 03, 2017 01:24PM UTC by scottgonzalez comment:5

#15224 is a duplicate of this ticket.

Changed August 04, 2017 05:51AM UTC by ksurakka comment:6

I think that this bug should not be closed, because the actual problem still exists. Before I wrote my (duplicate) bug report yesterday (thx for a quick response), I checked all open bugs but not the closed ones, which I think is a proper process.

Changed August 04, 2017 12:45PM UTC by scottgonzalez comment:7

description: While trying to determine what was slowing down my autocomplete text box, I noticed that every time the user types in the target text box the number of event listeners would go up. It looks like autocomplete (or the widget factory?) is adding duplicate "remove" events to the target. This can be reproduced by adding the following line to the default autocomplete example at https://jqueryui.com/autocomplete/ . \ \ \ {{{ \ response: function (e, ui) { \ console.log( jQuery._data( $("#tags")[0], "events" ) ); \ } \ }}} \ \ When looking at the results in chrome's developer tools I can see the number of event listeners go up every time the the user types in the target text box. \ \ \ {{{ \ \ Object {remove: Array[3], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[5], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[7], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[9], keydown: Array[1], keypress: Array[1], input: Array[1]... \ }}} \ \ http://plnkr.co/edit/Jk2xg3ZjJ5jS5mgP1zHZ?p=preview is a demo of the remove events growing. \ \ \ While trying to determine what was slowing down my autocomplete text box, I noticed that every time the user types in the target text box the number of event listeners would go up. It looks like autocomplete (or the widget factory?) is adding duplicate "remove" events to the target. This can be reproduced by adding the following line to the default autocomplete example at https://jqueryui.com/autocomplete/ . \ \ \ {{{ \ response: function (e, ui) { \ console.log( jQuery._data( $("#tags")[0], "events" ) ); \ } \ }}} \ \ When looking at the results in chrome's tools I can see the number of event listeners go up every time the the user types in the target text box. \ \ \ {{{ \ \ Object {remove: Array[3], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[5], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[7], keydown: Array[1], keypress: Array[1], input: Array[1]... \ Object {remove: Array[9], keydown: Array[1], keypress: Array[1], input: Array[1]... \ }}} \ \ http://plnkr.co/edit/Jk2xg3ZjJ5jS5mgP1zHZ?p=preview is a demo of the remove events growing. \ \ \

The proper process could also include:

  • Checking tickets that are closed with a future milestone (which would have found this ticket).
  • Testing against master to see if the bug still exists (which would have shown that it doesn't).

Neither of these steps are necessary for a reporter to follow, but we are definitely following a proper process. It would not make sense to keep tickets open they are released; tickets are closed when they are fixed. This is how every project I've ever seen has worked.

Changed August 05, 2017 12:07PM UTC by ksurakka comment:8

You are right, I should have checked those tickets as well and test against master, my bad.

It might be nice to see all open tickets and those that are already fixed but are targeted for a future version in a one list, I think it would be handy for developer. But as I said, my bad.

I did a new test against master version (https://jsfiddle.net/vm152La3/9/), and it works much better but still seems to slowly slow down when using Chome. I added console.log (in a breakpoint) to line 1596 in query-3.2.1.js to print the size of the results array and it seems to grow by every time a popup is shown. In Safari it grows as well but does not cause notifiable slowness.

And thank you and all developers for your work.

Changed August 05, 2017 12:22PM UTC by scottgonzalez comment:9

jquery-ui-git seems to have been broken for a long time. You'll notice the header comment says "jQuery UI - v1.12.0-pre - 2016-02-09"

Changed September 12, 2017 07:43PM UTC by scottgonzalez comment:10

#15237 is a duplicate of this ticket.