1
0
mirror of synced 2025-02-03 21:59:24 +03:00

Improve jQuery performance issues

This improves a regression added in b9b55cec4403f69d999ff6c3b90472805dfbed71
that reduced performance for large number of options when using a
jQuery collection object to append multiple options instead of
using a bare array containing the jQuery elements.

As `$.fn.add` is only required for jQuery 1.7.x, we can use a
utility function that only falls back to it for that specific
version of jQuery, and uses `$.fn.append` with an array for all
other versions.

This closes https://github.com/select2/select2/issues/3230.
This commit is contained in:
Kevin Brown 2015-04-05 20:08:33 -04:00
parent c24293f2ba
commit 4fc874a3ae
10 changed files with 90 additions and 33 deletions

View File

@ -714,6 +714,23 @@ S2.define('select2/utils',[
}); });
}; };
// Append an array of jQuery nodes to a given element.
Utils.appendMany = function ($element, $nodes) {
// jQuery 1.7.x does not support $.fn.append() with an array
// Fall back to a jQuery object collection using $.fn.add()
if ($.fn.jquery.substr(0, 3) === '1.7') {
var $jqNodes = $();
$.map($nodes, function (node) {
$jqNodes = $jqNodes.add(node);
});
$nodes = $jqNodes;
}
$element.append($nodes);
};
return Utils; return Utils;
}); });
@ -1565,7 +1582,7 @@ S2.define('select2/selection/multiple',[
return; return;
} }
var $selections = $(); var $selections = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
var selection = data[d]; var selection = data[d];
@ -1578,10 +1595,12 @@ S2.define('select2/selection/multiple',[
$selection.data('data', selection); $selection.data('data', selection);
$selections = $selections.add($selection); $selections.push($selection);
} }
this.$selection.find('.select2-selection__rendered').append($selections); var $rendered = this.$selection.find('.select2-selection__rendered');
Utils.appendMany($rendered, $selections);
}; };
return MultipleSelection; return MultipleSelection;
@ -3015,7 +3034,7 @@ S2.define('select2/data/select',[
}; };
SelectAdapter.prototype.addOptions = function ($options) { SelectAdapter.prototype.addOptions = function ($options) {
this.$element.append($options); Utils.appendMany(this.$element, $options);
}; };
SelectAdapter.prototype.option = function (data) { SelectAdapter.prototype.option = function (data) {
@ -3185,7 +3204,7 @@ S2.define('select2/data/array',[
return self.item($(this)).id; return self.item($(this)).id;
}).get(); }).get();
var $options = $(); var $options = [];
// Filter out all items except for the one passed in the argument // Filter out all items except for the one passed in the argument
function onlyItem (item) { function onlyItem (item) {
@ -3216,10 +3235,10 @@ S2.define('select2/data/array',[
if (item.children) { if (item.children) {
var $children = this.convertToOptions(item.children); var $children = this.convertToOptions(item.children);
$option.append($children); Utils.appendMany($option, $children);
} }
$options = $options.add($option); $options.push($option);
} }
return $options; return $options;
@ -3403,7 +3422,7 @@ S2.define('select2/data/tags',[
var $option = self.option(tag); var $option = self.option(tag);
$option.attr('data-select2-tag', true); $option.attr('data-select2-tag', true);
self.addOptions($option); self.addOptions([$option]);
self.insertTag(data, tag); self.insertTag(data, tag);
} }
@ -5468,8 +5487,8 @@ S2.define('select2/compat/inputData',[
}; };
InputData.prototype.addOptions = function (_, $options) { InputData.prototype.addOptions = function (_, $options) {
var options = $.map($options, function (option) { var options = $.map($options, function ($option) {
return $.data(option, 'data'); return $.data($option[0], 'data');
}); });
this._currentData.push.apply(this._currentData, options); this._currentData.push.apply(this._currentData, options);

File diff suppressed because one or more lines are too long

35
dist/js/select2.js vendored
View File

@ -714,6 +714,23 @@ S2.define('select2/utils',[
}); });
}; };
// Append an array of jQuery nodes to a given element.
Utils.appendMany = function ($element, $nodes) {
// jQuery 1.7.x does not support $.fn.append() with an array
// Fall back to a jQuery object collection using $.fn.add()
if ($.fn.jquery.substr(0, 3) === '1.7') {
var $jqNodes = $();
$.map($nodes, function (node) {
$jqNodes = $jqNodes.add(node);
});
$nodes = $jqNodes;
}
$element.append($nodes);
};
return Utils; return Utils;
}); });
@ -1565,7 +1582,7 @@ S2.define('select2/selection/multiple',[
return; return;
} }
var $selections = $(); var $selections = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
var selection = data[d]; var selection = data[d];
@ -1578,10 +1595,12 @@ S2.define('select2/selection/multiple',[
$selection.data('data', selection); $selection.data('data', selection);
$selections = $selections.add($selection); $selections.push($selection);
} }
this.$selection.find('.select2-selection__rendered').append($selections); var $rendered = this.$selection.find('.select2-selection__rendered');
Utils.appendMany($rendered, $selections);
}; };
return MultipleSelection; return MultipleSelection;
@ -3015,7 +3034,7 @@ S2.define('select2/data/select',[
}; };
SelectAdapter.prototype.addOptions = function ($options) { SelectAdapter.prototype.addOptions = function ($options) {
this.$element.append($options); Utils.appendMany(this.$element, $options);
}; };
SelectAdapter.prototype.option = function (data) { SelectAdapter.prototype.option = function (data) {
@ -3185,7 +3204,7 @@ S2.define('select2/data/array',[
return self.item($(this)).id; return self.item($(this)).id;
}).get(); }).get();
var $options = $(); var $options = [];
// Filter out all items except for the one passed in the argument // Filter out all items except for the one passed in the argument
function onlyItem (item) { function onlyItem (item) {
@ -3216,10 +3235,10 @@ S2.define('select2/data/array',[
if (item.children) { if (item.children) {
var $children = this.convertToOptions(item.children); var $children = this.convertToOptions(item.children);
$option.append($children); Utils.appendMany($option, $children);
} }
$options = $options.add($option); $options.push($option);
} }
return $options; return $options;
@ -3403,7 +3422,7 @@ S2.define('select2/data/tags',[
var $option = self.option(tag); var $option = self.option(tag);
$option.attr('data-select2-tag', true); $option.attr('data-select2-tag', true);
self.addOptions($option); self.addOptions([$option]);
self.insertTag(data, tag); self.insertTag(data, tag);
} }

File diff suppressed because one or more lines are too long

View File

@ -116,8 +116,8 @@ define([
}; };
InputData.prototype.addOptions = function (_, $options) { InputData.prototype.addOptions = function (_, $options) {
var options = $.map($options, function (option) { var options = $.map($options, function ($option) {
return $.data(option, 'data'); return $.data($option[0], 'data');
}); });
this._currentData.push.apply(this._currentData, options); this._currentData.push.apply(this._currentData, options);

View File

@ -35,7 +35,7 @@ define([
return self.item($(this)).id; return self.item($(this)).id;
}).get(); }).get();
var $options = $(); var $options = [];
// Filter out all items except for the one passed in the argument // Filter out all items except for the one passed in the argument
function onlyItem (item) { function onlyItem (item) {
@ -66,10 +66,10 @@ define([
if (item.children) { if (item.children) {
var $children = this.convertToOptions(item.children); var $children = this.convertToOptions(item.children);
$option.append($children); Utils.appendMany($option, $children);
} }
$options = $options.add($option); $options.push($option);
} }
return $options; return $options;

View File

@ -151,7 +151,7 @@ define([
}; };
SelectAdapter.prototype.addOptions = function ($options) { SelectAdapter.prototype.addOptions = function ($options) {
this.$element.append($options); Utils.appendMany(this.$element, $options);
}; };
SelectAdapter.prototype.option = function (data) { SelectAdapter.prototype.option = function (data) {

View File

@ -71,7 +71,7 @@ define([
var $option = self.option(tag); var $option = self.option(tag);
$option.attr('data-select2-tag', true); $option.attr('data-select2-tag', true);
self.addOptions($option); self.addOptions([$option]);
self.insertTag(data, tag); self.insertTag(data, tag);
} }

View File

@ -76,7 +76,7 @@ define([
return; return;
} }
var $selections = $(); var $selections = [];
for (var d = 0; d < data.length; d++) { for (var d = 0; d < data.length; d++) {
var selection = data[d]; var selection = data[d];
@ -89,10 +89,12 @@ define([
$selection.data('data', selection); $selection.data('data', selection);
$selections = $selections.add($selection); $selections.push($selection);
} }
this.$selection.find('.select2-selection__rendered').append($selections); var $rendered = this.$selection.find('.select2-selection__rendered');
Utils.appendMany($rendered, $selections);
}; };
return MultipleSelection; return MultipleSelection;

View File

@ -241,5 +241,22 @@ define([
}); });
}; };
// Append an array of jQuery nodes to a given element.
Utils.appendMany = function ($element, $nodes) {
// jQuery 1.7.x does not support $.fn.append() with an array
// Fall back to a jQuery object collection using $.fn.add()
if ($.fn.jquery.substr(0, 3) === '1.7') {
var $jqNodes = $();
$.map($nodes, function (node) {
$jqNodes = $jqNodes.add(node);
});
$nodes = $jqNodes;
}
$element.append($nodes);
};
return Utils; return Utils;
}); });