Все остальные браузеры почти мгновенно обрабатывают этот JS, см. Тесты ниже.

Он замедляется только в этом коде в функции (отдых выполняется мгновенно), что настолько просто, что я запутался в том, что я могу сделать, чтобы это исправить.

Я не могу воспроизвести это в JSFiddle, вот эквивалентный код https://jsfiddle.net/5ax7mshz/. Я вижу с помощью performance.now (), что это единственный код, замедляющий его в нашем приложении, и это чисто приложение JS + JQ, здесь нет других переменных ... почему-то в нашем приложении это занимает в 600 раз больше времени, чем это происходит на скрипке. Здесь очень много ума.

Спасибо всем!

var options = "";
for (var i = 0; i < data.Vendor.length; i++) {
    options += "<option value='" + data.Vendor[i].VendorID + "'>" + data.Vendor[i].Name + "</option>";
}
$el.append(options);

Фактические контрольные значения

Средний тест Edge (попытки некоторых решений здесь, к сожалению, все еще привели к аналогичным значениям)

  • 28155 мс всего
    • 6968 мс список1 (2232 элемента)
    • 21179 мс, список2 (4016 элементов)
    • 7,6 мс список3 (10 элементов)

Вот Chrome, если хочешь посмеяться

  • 55,07 мс всего
    • 21,09 мс, список1 (2232 элемента)
    • 32,18 мс, список2 (4016 элементов)
    • 1,79 мс список3 (10 элементов)

Aaaand Firefox занимает всего 46 мс

enter image description here

enter image description here

1
SPillai 2 Сен 2020 в 22:21

2 ответа

Лучший ответ

В итоге сделали это, по крайней мере, всего 5-7 секунд (5000-7000 мс) вместо 28, что «нормально», поскольку это влияет только на пару клиентов, остальные используют Chrome (50 мс) и FF (40 мс) и IE11 + ( 300 мс)

document.getElementById("vendor").innerHTML = "";
var i = 0;
var loop_num = 0;
var vendorCount = data.Vendor.length;
var vendorPiece;
var k = 0;
var options = [];
if (isEdge) {
  //add optgroups to select
  var num_selects = Math.ceil(vendorCount / 1000); //say, 3 for 2323
  for (var jj = 1; jj <= num_selects; jj++) {
    var optgroup = document.createElement("optgroup");
    optgroup.label = "";
    optgroup.id = "vendor" + jj;
    document.getElementById("vendor").appendChild(optgroup);
    if (jj == 1) {
      var blankopt = document.createElement("option");
      blankopt.value = "";
      blankopt.text = "";
      document.getElementById("vendor" + jj).appendChild(blankopt);
    }
  }
} else {
  var blankopt = document.createElement("option");
  blankopt.value = "";
  blankopt.text = "";
  document.getElementById("vendor").appendChild(blankopt);
}
while (i < vendorCount) {
  var pieceEndIndex =
    Math.min(1000, vendorCount - i) == 1000 ? i + 1000 : vendorCount;
  k = 0;
  options = [];
  vendorPiece = data.Vendor.slice(i, pieceEndIndex);
  for (var j = 0; j < vendorPiece.length; j++) {
    var vendor = vendorPiece[j];
    options[k++] = "<option value='";
    options[k++] = vendor.VendorID;
    options[k++] = "'>";
    options[k++] = vendor.Name;
    options[k++] = "</option>";
  }
  var vendor_id = !isEdge ? "vendor" : "vendor" + (loop_num + 1);
  document.getElementById(vendor_id).innerHTML += options.join("");
  i += vendorPiece.length;
  loop_num++;
}
0
Rudu 3 Сен 2020 в 14:02

Используете ли вы append из jQuery?

У меня нет Edge на этой машине, но у меня есть IE, поэтому я буду использовать его как разумный эквивалент. Я пробовал несколько сборок с 4000 опциями выбора:

  1. Конкатенация строк, за которой следует один jQuery append
  2. jQuery append за запись
  3. appendChild на элемент (без jQuery)
  4. добавить new Option(... в select.options (без jQuery)

Для расчета времени я использую

console.time('build');
build();
console.timeEnd('build');

И результаты, два прогона - самое быстрое время (мс):

IE11 805 2120 605 6033
FF80  48  190  26   21
CR84  95  342  52  214

С 4000 элементов это сравнение с вашим списком2, в то время как первое временное число должно соответствовать вашим результатам (хотя обратите внимание, что я составил значение / текст для каждой записи, поскольку у меня нет доступа к вашему списку). Обратите внимание, что Chrome значительно медленнее вашего (95 против 32 - 3x), а IE значительно быстрее (805 против 2117 - 26x). Для моего процесса Chrome у меня есть много открытых вкладок, но есть также ожидание обновления, для моего процесса IE у меня больше ничего не открыто, но это также не совсем то же самое, что и Edge (при условии, что вы не используете Webkit Edge - если да, тогда это совсем другой двигатель)

Сборки на основе jQuery плохо работают. Это не совсем честная борьба, поскольку этот метод должен анализировать строку и интерпретировать ее как HTML. Сборка 4 также плохо справлялась со всем, кроме FireFox. Итак, похоже, что ванильный javascript с appendChild - лучший подход.

Чтобы сопоставить это с вашими данными (которые могут иметь дополнительные задержки доступа к объектам):

function build(data, select) {
  var n=data.Vendor.length;
  for (var i=0; i<n; i++) {
    var item=data.Vendor[i];
    var opt=document.createElement("option");
    opt.value=item.VendorID;
    opt.innerText=item.Name;
    select.appendChild(opt);
  }
}
// Call egs:
// build(data, document.getElementById("itemList"));
// build(data, document.forms[0].itemSelect);
0
Rudu 2 Сен 2020 в 21:55