From 0c5becce0e395b89de0f526e857e7ca2717d4ab2 Mon Sep 17 00:00:00 2001 From: Michał Gołębiowski-Owczarek Date: Sat, 15 Jan 2022 01:26:23 +0100 Subject: Widget: Optimize attachment of the _untrackClassesElement listener jQuery UI 1.13.0 changed the logic attaching the `_untrackClassesElement` listener in the `_classes` widget method; one of the side effects was calling `this._on` for each node that needed the listener. That caused a severe performance degradation for large comboboxes as each `_on` jQuery UI call causes a jQuery `add` call that calls Sizzle's `uniqueSort` underneath. Instead, collect the nodes that need the listener and then, outside of the loop, create a jQuery object out of them and attach the listener once. That's still slower than the jQuery 1.12 version but only slightly: 936 ms to 1.03s on a very large list on a recent MacBook Pro, compared to ~30 seconds before this patch. Fixes gh-2014 Closes gh-2037 --- ui/widget.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'ui') diff --git a/ui/widget.js b/ui/widget.js index 04daaa883..69240f92c 100644 --- a/ui/widget.js +++ b/ui/widget.js @@ -499,6 +499,8 @@ $.Widget.prototype = { }, options ); function bindRemoveEvent() { + var nodesToBind = []; + options.element.each( function( _, element ) { var isTracked = $.map( that.classesElementLookup, function( elements ) { return elements; @@ -508,11 +510,13 @@ $.Widget.prototype = { } ); if ( !isTracked ) { - that._on( $( element ), { - remove: "_untrackClassesElement" - } ); + nodesToBind.push( element ); } } ); + + that._on( $( nodesToBind ), { + remove: "_untrackClassesElement" + } ); } function processClassString( classes, checkOption ) { -- cgit v1.2.3