ソースを参照

Improve option generate speed

Now the options are mostly generated by hand before being passed
off to jQuery for templating. This fixes much of the speed issues
we had when they were entirely being generated through jQuery.
Kevin Brown 10 年 前
コミット
56dbbf8cdb

+ 35 - 21
dist/js/select2.amd.full.js

@@ -261,16 +261,44 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
-    var $option = $(
-      '<li class="option" role="treeitem" aria-selected="false"></li>'
-    );
+    var attrs = {
+      'class': 'option',
+      'role': 'treeitem',
+      'aria-selected': 'false'
+    };
+
+    if (data.disabled) {
+      delete attrs['aria-selected'];
+      attrs['aria-disabled'] = 'true';
+    }
+
+    if (data.id == null) {
+      delete attrs['aria-selected'];
+    }
+
+    if (data._resultId != null) {
+      attrs.id = data._resultId;
+    }
 
     if (data.children) {
-      $option
-        .attr('role', 'group')
-        .attr('aria-label', data.text)
-        .removeAttr('aria-selected');
+      attrs.role = 'group';
+      attrs['aria-label'] = data.text;
+      delete attrs['aria-selected'];
+    }
+
+    var html = '<li';
+
+    for (var attr in attrs) {
+      var val = attrs[attr];
 
+      html += ' ' + attr + '="' + val + '"';
+    }
+
+    html += '></li>';
+
+    var $option = $(html);
+
+    if (data.children) {
       var $label = $('<strong class="group-label"></strong>');
       this.template(data, $label);
 
@@ -294,20 +322,6 @@ define('select2/results',[
       this.template(data, $option);
     }
 
-    if (data.disabled) {
-      $option
-        .removeAttr('aria-selected')
-        .attr('aria-disabled', 'true');
-    }
-
-    if (data.id == null) {
-      $option.removeAttr('aria-selected');
-    }
-
-    if (data._resultId != null) {
-      $option.attr('id', data._resultId);
-    }
-
     $option.data('data', data);
 
     return $option;

+ 35 - 21
dist/js/select2.amd.js

@@ -261,16 +261,44 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
-    var $option = $(
-      '<li class="option" role="treeitem" aria-selected="false"></li>'
-    );
+    var attrs = {
+      'class': 'option',
+      'role': 'treeitem',
+      'aria-selected': 'false'
+    };
+
+    if (data.disabled) {
+      delete attrs['aria-selected'];
+      attrs['aria-disabled'] = 'true';
+    }
+
+    if (data.id == null) {
+      delete attrs['aria-selected'];
+    }
+
+    if (data._resultId != null) {
+      attrs.id = data._resultId;
+    }
 
     if (data.children) {
-      $option
-        .attr('role', 'group')
-        .attr('aria-label', data.text)
-        .removeAttr('aria-selected');
+      attrs.role = 'group';
+      attrs['aria-label'] = data.text;
+      delete attrs['aria-selected'];
+    }
+
+    var html = '<li';
+
+    for (var attr in attrs) {
+      var val = attrs[attr];
 
+      html += ' ' + attr + '="' + val + '"';
+    }
+
+    html += '></li>';
+
+    var $option = $(html);
+
+    if (data.children) {
       var $label = $('<strong class="group-label"></strong>');
       this.template(data, $label);
 
@@ -294,20 +322,6 @@ define('select2/results',[
       this.template(data, $option);
     }
 
-    if (data.disabled) {
-      $option
-        .removeAttr('aria-selected')
-        .attr('aria-disabled', 'true');
-    }
-
-    if (data.id == null) {
-      $option.removeAttr('aria-selected');
-    }
-
-    if (data._resultId != null) {
-      $option.attr('id', data._resultId);
-    }
-
     $option.data('data', data);
 
     return $option;

+ 35 - 21
dist/js/select2.full.js

@@ -9796,16 +9796,44 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
-    var $option = $(
-      '<li class="option" role="treeitem" aria-selected="false"></li>'
-    );
+    var attrs = {
+      'class': 'option',
+      'role': 'treeitem',
+      'aria-selected': 'false'
+    };
+
+    if (data.disabled) {
+      delete attrs['aria-selected'];
+      attrs['aria-disabled'] = 'true';
+    }
+
+    if (data.id == null) {
+      delete attrs['aria-selected'];
+    }
+
+    if (data._resultId != null) {
+      attrs.id = data._resultId;
+    }
 
     if (data.children) {
-      $option
-        .attr('role', 'group')
-        .attr('aria-label', data.text)
-        .removeAttr('aria-selected');
+      attrs.role = 'group';
+      attrs['aria-label'] = data.text;
+      delete attrs['aria-selected'];
+    }
+
+    var html = '<li';
+
+    for (var attr in attrs) {
+      var val = attrs[attr];
 
+      html += ' ' + attr + '="' + val + '"';
+    }
+
+    html += '></li>';
+
+    var $option = $(html);
+
+    if (data.children) {
       var $label = $('<strong class="group-label"></strong>');
       this.template(data, $label);
 
@@ -9829,20 +9857,6 @@ define('select2/results',[
       this.template(data, $option);
     }
 
-    if (data.disabled) {
-      $option
-        .removeAttr('aria-selected')
-        .attr('aria-disabled', 'true');
-    }
-
-    if (data.id == null) {
-      $option.removeAttr('aria-selected');
-    }
-
-    if (data._resultId != null) {
-      $option.attr('id', data._resultId);
-    }
-
     $option.data('data', data);
 
     return $option;

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/js/select2.full.min.js


+ 35 - 21
dist/js/select2.js

@@ -689,16 +689,44 @@ define('select2/results',[
   };
 
   Results.prototype.option = function (data) {
-    var $option = $(
-      '<li class="option" role="treeitem" aria-selected="false"></li>'
-    );
+    var attrs = {
+      'class': 'option',
+      'role': 'treeitem',
+      'aria-selected': 'false'
+    };
+
+    if (data.disabled) {
+      delete attrs['aria-selected'];
+      attrs['aria-disabled'] = 'true';
+    }
+
+    if (data.id == null) {
+      delete attrs['aria-selected'];
+    }
+
+    if (data._resultId != null) {
+      attrs.id = data._resultId;
+    }
 
     if (data.children) {
-      $option
-        .attr('role', 'group')
-        .attr('aria-label', data.text)
-        .removeAttr('aria-selected');
+      attrs.role = 'group';
+      attrs['aria-label'] = data.text;
+      delete attrs['aria-selected'];
+    }
+
+    var html = '<li';
+
+    for (var attr in attrs) {
+      var val = attrs[attr];
 
+      html += ' ' + attr + '="' + val + '"';
+    }
+
+    html += '></li>';
+
+    var $option = $(html);
+
+    if (data.children) {
       var $label = $('<strong class="group-label"></strong>');
       this.template(data, $label);
 
@@ -722,20 +750,6 @@ define('select2/results',[
       this.template(data, $option);
     }
 
-    if (data.disabled) {
-      $option
-        .removeAttr('aria-selected')
-        .attr('aria-disabled', 'true');
-    }
-
-    if (data.id == null) {
-      $option.removeAttr('aria-selected');
-    }
-
-    if (data._resultId != null) {
-      $option.attr('id', data._resultId);
-    }
-
     $option.data('data', data);
 
     return $option;

ファイルの差分が大きいため隠しています
+ 0 - 0
dist/js/select2.min.js


+ 9 - 0
docs/examples.html

@@ -473,6 +473,15 @@ $.fn.select2.amd.require(
 
   var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];
 
+  var data = [];
+
+  for (var i = 0; i < 9999; i++) {
+    data.push({
+      id: i.toString(),
+      text: i
+    });
+  }
+
   var $ajax = $(".js-example-data-ajax");
 
   var $disabledResults = $(".js-example-disabled-results");

+ 35 - 21
src/js/select2/results.js

@@ -107,16 +107,44 @@ define([
   };
 
   Results.prototype.option = function (data) {
-    var $option = $(
-      '<li class="option" role="treeitem" aria-selected="false"></li>'
-    );
+    var attrs = {
+      'class': 'option',
+      'role': 'treeitem',
+      'aria-selected': 'false'
+    };
+
+    if (data.disabled) {
+      delete attrs['aria-selected'];
+      attrs['aria-disabled'] = 'true';
+    }
+
+    if (data.id == null) {
+      delete attrs['aria-selected'];
+    }
+
+    if (data._resultId != null) {
+      attrs.id = data._resultId;
+    }
 
     if (data.children) {
-      $option
-        .attr('role', 'group')
-        .attr('aria-label', data.text)
-        .removeAttr('aria-selected');
+      attrs.role = 'group';
+      attrs['aria-label'] = data.text;
+      delete attrs['aria-selected'];
+    }
 
+    var html = '<li';
+
+    for (var attr in attrs) {
+      var val = attrs[attr];
+
+      html += ' ' + attr + '="' + val + '"';
+    }
+
+    html += '></li>';
+
+    var $option = $(html);
+
+    if (data.children) {
       var $label = $('<strong class="group-label"></strong>');
       this.template(data, $label);
 
@@ -140,20 +168,6 @@ define([
       this.template(data, $option);
     }
 
-    if (data.disabled) {
-      $option
-        .removeAttr('aria-selected')
-        .attr('aria-disabled', 'true');
-    }
-
-    if (data.id == null) {
-      $option.removeAttr('aria-selected');
-    }
-
-    if (data._resultId != null) {
-      $option.attr('id', data._resultId);
-    }
-
     $option.data('data', data);
 
     return $option;

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません