Насколько дорогими являются вызовы функций JS (по сравнению с выделением памяти для переменной)?
-
02-07-2019 - |
Вопрос
Учитывая некоторый JS-код, подобный этому:
for (var i = 0; i < document.getElementsByName('scale_select').length; i++) {
document.getElementsByName('scale_select')[i].onclick = vSetScale;
}
Будет ли код работать быстрее, если мы поместим результат getElementsByName в переменную перед циклом, а затем будем использовать эту переменную после этого?
Я не уверен, насколько велик эффект в реальной жизни, учитывая результат getElementsByName
обычно имеет < 10 элементов.В любом случае мне хотелось бы понять основную механику.
Кроме того, если есть что-нибудь еще примечательное в этих двух вариантах, сообщите мне.
Решение
Определенно.Память, необходимая для хранения, будет только указателем на объект DOM, и это существенно менее болезненно, чем выполнять поиск по DOM каждый раз, когда вам нужно что-то использовать!
Идеальный код:
var scale_select = document.getElementsByName('scale_select');
for (var i = 0; i < scale_select.length; i++)
scale_select[i].onclick = vSetScale;
Другие советы
Кэширование поиска свойств может кому-то помочь, но cУвеличение длины массива перед запуском цикла оказалось быстрее.
Таким образом, объявление в цикле переменной, содержащей значение Scale_select.length, несколько ускорит весь цикл.
var scale_select = document.getElementsByName('scale_select');
for (var i = 0, al=scale_select.length; i < al; i++)
scale_select[i].onclick = vSetScale;
Разумная реализация DOM будет выполнять собственное кэширование, аннулируя кеш при каких-либо изменениях.Но не все DOM сегодня могут быть такими умными (кашель ИЕ кашель), поэтому лучше, если вы сделаете это сами.
В принципе, будет ли код работать быстрее, если мы поместим результат getElementsByName в переменную перед циклом, а затем будем использовать эту переменную после этого?
да.
Используйте переменные.Они не очень дороги в JavaScript, а вызовы функций определенно медленнее.Если вы выполняете цикл по крайней мере 5 раз по document.getElementById(), используйте переменную.Идея здесь не только в том, что вызов функции медленный, но и в том, что эта конкретная функция очень медленная, поскольку пытается найти элемент с заданным идентификатором в DOM.
@ Оли
Кэширование свойства длины элементов, выбранных в переменной, также является хорошей идеей:
var scaleSelect = document.getElementsByName('scale_select');
var scaleSelectLength = scaleSelect.length;
for (var i = 0; i < scaleSelectLength; i += 1)
{
// scaleSelect[i]
}
Нет смысла хранить ScaleSelect.length в отдельной переменной;на самом деле он уже есть: ScaleSelect.length — это просто атрибут массива ScaleSelect, и поэтому доступ к нему так же быстр, как и к любой другой статической переменной.
Я так думаю.Каждый раз, когда он зацикливается, механизму необходимо повторно оценить оператор document.getElementsByName.
С другой стороны, если значение сохранено в переменной, то оно уже имеет значение.