Оптимизация производительности с помощью регулирования в JavaScript

Оптимизация производительности с помощью регулирования в JavaScript

6 января 2023 г.

Некоторые события браузера имеют очень высокую частоту. Количество таких событий, как перемещение курсора, прокрутка, изменение размера окна браузера, удерживание клавиши и т. д., может достигать 100 раз в секунду. Функции, вызываемые при такой частоте событий, сильно нагружают браузер, что приводит к снижению производительности.

В качестве примера напишем простой обработчик события изменения размера окна:

const handleResize = () => {
    const { innerHeigh, innerWidth } = window;
    console.log({ innerHeigh, innerWidth });
}

window.addEventListener('resize', handleResize)

Попробуйте запустить этот код в консоли браузера и изменить размер окна, и вы увидите, что эта функция вызывается десятки раз даже при небольшом изменении размера.

А теперь представьте, что функция handleResize имеет не только вывод в консоль, но и ряд операций со сложными манипуляциями с DOM: в этом случае реакция браузера на отрисовку резко замедлится. Как можно оптимизировать этот процесс? Чтобы снизить нагрузку на браузер, необходимо использовать дросселирование.

Как использовать регулирование?

Троттлинг позволяет "замедлить" функцию, т.е. функция будет выполняться не более одного раза за указанный период, даже если она вызывается много раз в течение этого периода. Например, если для события прокрутки страницы вы установите время 100 мс, функция будет выполняться каждые 100 мс во время прокрутки.

Схематически это можно отобразить следующим образом:

Многие библиотеки JavaScript, такие как lodash, underscore, rxjs, предлагают метод дросселирования с различными дополнительными функциями. Ниже вы можете прочитать довольно распространенную реализацию метода дросселя:

function throttle(fn, time) {
    let timeout = null;
    return function () {
        if(timeout) return;
        const context = this;
        const args = arguments;
        const later = () => {
            fn.call(context, ...args);
            timeout = null;
        }
        timeout = setTimeout(later, time);
    }
}

Вернемся к примеру с обработчиком события изменения размера окна и увидим, что обработчик дросселя вызывается гораздо реже (в демонстрационных целях установлено значение 500 мс):

const handleResize = () => {
    const { innerHeigh, innerWidth } = window;
    console.log({ innerHeigh, innerWidth });
}

const handleResizeThrottled = throttle(handleResize, 500);

window.addEventListener('resize', handleResizeThrottled);

Таким образом, независимо от того, как часто вызывается какое-либо событие, регулирование не позволит нужной функции запускаться слишком часто и снизит нагрузку на браузер.

Заключение

Это все, что я хотел сказать о функции дроссельной заслонки. Надеюсь, моя статья вам понравилась и оказалась полезной.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE