Йо-йо! Операции с DOM в JavaScript вызывают попа-боль, когда их много и они часто возникают. Например, если у нас отрисовка нашего приложения зависит от JavaScript’а, то такое событие как resize на window может нам существенно нагрузить устройство.
Если говорить коротко, то нам нужно ускорить наше приложение, которое срабатывает на какое-то js-событие. Далее мы разберемся как ускорить js-приложение с помощью так называемого тротлинга.
Как уже некоторым известно, я занимаюсь разработкой собственной js-библиотеки для управления размерами элементов «Stickjaw» и в ней тоже есть такая проблема которую я уже решил.
Это как раз пример из моей библиотеки. Суть задачи: во время resize размеры «тянущихся» блоков должны пересчитаться, иногда их очень много. Предел количества элементов у меня достигал 1000 (правда это синтетическое значение).
SJ = function(){ this.windowResizeToggle = false; // Другой код } SJ.prototype.windowResize = function(){ window.addEventListener('resize', ()=>{ if(this.windowResizeToggle === false){ this.windowResizeToggle = true; setTimeout(()=>{ this.updateBreakPointBuffer(); this.init(); this.windowResizeToggle = false; }, 100); } }, false); }
Суть этого кода следующая: Если переменная this.windowResizeToggle === false, то сделать её равной true и запустить setTimeout, в котором уже происходят те функции, которые мне нужно запустить для преобразования с DOM. После преобразований я переключаю
this.windowResizeToggle на значение true.
В момент изменения размера экрана, событие resize может вызываться кучу раз. Такой фокус с переменной this.windowResizeToggle позволяет не запускать пересчёт на каждое событие.
Пример 1 в отличие от последующих реален, 2 и 3 пример будут из учебника «JavaScript для профессиональных web-разработчиков». Не ругайтесь на несколько устаревший «код-стайл» без let, const и arrow function. Сути это не меняет. В общем код:
var processor = { timeoutID: null, // метод, выполняющий обработку performProcessing: function(){ // код обработки }, // метод, инициирующий обработку process: function(){ clearTimeout(this.timeoutID); var that = this; this.timeoutID = setTimeout(function(){ that.performProcessing }, 100); } }; // Попытка начать обработку processor.process();
Важной особенностью этого примера является отмена предыдущих вызовов метода performProcessing(), путём удаления timeoutID функцией clearTimeout().
Третий пример по сути упрощённая версия примера №2, но выглядит намного изящнее.
function throttle(method, context){ clearTimeout(method.tID); method.tID = setTimeout(function(){ method.call(context); }, 100); }
Функция throttle() принимает два аргумента: функцию, которую нужно выполнить и область видимости, в которой ее нужно выполнить. Если второй аргумент не указан, метод выполнится в глобальной области видимости.
Автор книги привёл пример, который мне очень близок, а именно там показано изменение размеров элемента. В его примере указано следующие:
function resizeDiv(){ var div = document.getElementById("myDiv"); div.style.height = div.offsetWidth + "px"; } window.onresize = function(){ throttle(resizeDiv); }
Такое регулирование функций следует использовать, если какой-то код нужно выполнять только периодически. Но при этом нельзя контролировать частоту его запуска, вы не можете.
Надеюсь вам понравилась моя статья и она принесёт вам пользу. Поделитесь статьёй со своими коллегами и вместе создавайте сложные js-приложения. Подписывайтесь на меня в соц.сетях, пишите в instagram или vk (ссылки в футере), не стесняйтесь задавать вопросы в личку!)