Какой способ изменения коллекции элементов JS быстрее в jQuery

#javascript #jquery #performance

#javascript #jquery #Производительность

Вопрос:

У меня есть кнопка выбора всех, которую я хочу реализовать. Какой способ быстрее?

 $('.check-box').prop('disabled', false).trigger('change');
  

Или

 $('.check-box').each(function(index, element){
    $(element).prop('disabled', false).trigger('change');
});
  

В пользовательском интерфейсе они делают то же самое.
Похоже, что второй не только выбирает по имени класса, но и выбирает каждый элемент, и это операция O (MN). Но возможно ли, что первый подход просто делает именно то, что второй подход делает за кулисами (хотя это сделает первый подход более выгодным, поскольку он содержит меньше кода, что ускоряет время загрузки)?

Комментарии:

1. вероятно, очень похоже и на самом деле не имеет значения… но вы могли бы выполнить тест jsperf.

2. со сколькими элементами вы имеете дело?

Ответ №1:

Большинство методов jQuery имеют внутренний each и выглядят в основном как:

 // $.fn is where chainable methods reside 
$.fn.methodName = function(){

   // "this" is the jQuery object that contains collection of elements 
   // returned by either $(selector) or prior method in chain

   // return "this" for chaining and loop over all elements in collection
   return this.each(function(){
       // "this" is individual element instance

       // do same thing to each element here
   });
}
  

Так вот как $('.check-box').prop('disabled', false).trigger('change'); повлияет на все элементы с class="check-box"

Ответ №2:

Вот простой эквивалент JavaScript, который быстрее, чем что-либо jQuery jQuery в Chrome, но медленнее, чем jQuery в Firefox (как указал charlietfl) . jsPerf.

  • Собирать по классу

  • Выполните итерацию по каждому

  • Измените disabled атрибут / свойство

  • Щелкните каждый узел.

Первый пример jQuery выполняется быстрее, чем второй пример jQuery. Наиболее очевидное отличие заключается в том, что .each() метод является одним дополнительным шагом. $('.check-box') как и все объекты jQuery, имеет внутренний способ итерации через себя.

Демонстрация 1

 document.querySelectorAll('.check-box').forEach(node => { 
  node.disabled = false;
  node.click();
});  
 <input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>
<input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>
<input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>  

Демонстрация 2

 const cBox = document.getElementsByClassName('check-box');
for (let i = 0; i < cBox.length; i  ) {
  cBox[i].disabled = false;
  cBox[i].click();
}  
 <input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>
<input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>
<input class='check-box' type='checkbox' disabled>
<input class='check-box' type='checkbox' disabled checked>  

Комментарии:

1. Удивительно, но вы только что дважды запустили свой jsperf в Firefox… первый метод jQuery был самым быстрым из 3 на несколько процентов. Может быть быстрее изменить свойство, а не атрибут… node.disabled = false

2. В этом случае getElementsByClassName может быть быстрее? gomakethings.com/javascript-selector-performance

3. Также forEach не совместим с IE 6-8

4. @charlietfl действительно ли вы думаете, что это оптимизация для версии 8?

5. @DylanCzenski Я думаю, что вы, возможно, правы, разница в том, что getElementsByClassName возвращает live HTMLCollection и querySelectorAll возвращает «статический» список узлов, может быть?