0Pricing
React Academy · Урок

Зачем нужны debounce и throttle в интерфейсах

Разберитесь в цене необработанных ограничений частоты для обработчиков нажатий клавиш, прокрутки и изменения размера, а также узнайте, когда применять каждое решение

«Зачем нужны debounce и throttle в интерфейсах» — бесплатный урок React Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Пользовательские события с высокой частотой

Некоторые события DOM происходят с чрезвычайно высокой частотой. Событие keypress происходит при каждом нажатии клавиши. Событие scroll происходит десятки раз в секунду во время прокрутки. Событие resize происходит непрерывно, пока пользователь перетаскивает границу окна. Обработка каждого события по отдельности может перегрузить и браузер, и сервер.

Цена неограниченных обработчиков

Если обработчик нажатия клавиш выполняет сетевой запрос при каждом нажатии, пользователь, набирающий «хуки React» (11 символов), создаёт 11 сетевых запросов, большинство из которых относится к неполным поисковым запросам. Аналогично, обновление анимации параллакса на каждом пикселе прокрутки приводит к сотням повторных рендерингов React в секунду. Это расходует CPU, сеть и заряд батареи.

Что делает отложенный вызов

Отложенный вызов задерживает выполнение, пока событие не перестанет срабатывать в течение заданного периода. Если пользователь продолжает печатать, таймер сбрасывается после каждого нажатия клавиши. Только после N миллисекунд тишины обработчик наконец выполнится один раз. Отложенный вызов отвечает на вопрос: «запустить это после того, как пользователь закончит действие».

Что делает ограничение частоты

Ограничение частоты допускает выполнение не чаще одного раза за интервал времени, независимо от количества происходящих событий. Если пользователь быстро прокручивает страницу, ограничение в 100 мс гарантирует, что обработчик будет выполняться не более 10 раз в секунду. Ограничение частоты отвечает на вопрос: «запускать это регулярно, но не чаще одного раза в N мс».

Когда использовать отложенный вызов

Отложенный вызов подходит, когда вас интересует только конечное значение после остановки пользователя. Классические случаи: поле ввода поиска (отправка сетевого запроса после паузы в наборе), обработчик изменения размера окна (пересчёт макета после завершения изменения размера) и проверка поля формы с обращением к серверу (ожидание полного ввода перед проверкой).

Когда ограничивать частоту

Ограничение частоты подходит, когда во время непрерывной активности нужны регулярные обновления. Классические случаи: обработчик положения прокрутки (обновление индикатора прогресса чтения или закреплённого заголовка с частотой не более 30 кадров/с), отслеживание перемещения мыши (запись положения курсора для аналитики) и обработчики событий перетаскивания (плавное обновление положения перемещаемого элемента без лишней нагрузки).

Наивные реализации таят подводные камни

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

lodash.debounce и lodash.throttle

Lodash предоставляет _.debounce(fn, wait) и _.throttle(fn, wait) с параметрами для поведения при первом и последнем срабатывании. Возвращаемая функция имеет метод .cancel() для отмены ожидающего вызова и метод .flush() для его немедленного выполнения. В React их следует оборачивать в useRef, чтобы избежать создания заново при повторном рендеринге.

Бюджет производительности

Даже 50 дополнительных повторных рендерингов React в секунду из-за обработчика прокрутки без ограничения частоты могут заметно загрузить CPU, особенно на недорогих мобильных устройствах. Бюджет кадра в 16 мс (60 кадров/с) означает, что каждый повторный рендеринг должен завершаться менее чем за 16 миллисекунд, чтобы избежать пропущенных кадров. Отложенный вызов и ограничение частоты — ваша первая линия защиты от проблем с частотой кадров.

Обработчик события и обновление состояния

Не всем обработчикам событий с высокой частотой нужен отложенный вызов. Если обработчик лишь считывает значение, не обновляя состояние и не выполняя сетевые запросы, — например, записывает последнее положение мыши в объект ссылки, — отложенный вызов не требуется. Ограничивайте частоту только у обработчиков, запускающих затратные операции: обновление состояния, сетевые запросы или измерения DOM.

Отмена отложенных функций

При размонтировании компонента любой ожидающий отложенный вызов следует отменить, чтобы предотвратить обновление состояния после размонтирования. Если вы используете useRef для хранения отложенной функции, вызовите debouncedFn.cancel() в функции очистки useEffect. Отложенные функции Lodash предоставляют этот метод именно для такой цели.

Использование отложенного вызова и ограничения частоты

Какой приём следует использовать, чтобы выполнить сетевой запрос, когда пользователь перестаёт печатать в поле поиска?

Итоги урока: отложенный вызов и ограничение частоты

События с высокой частотой, такие как keypress, scroll и resize, могут вызывать проблемы с производительностью, если обработчики выполняются при каждом событии. Отложенный вызов ждёт тишины и лучше всего подходит для полей поиска и обработчиков изменения размера. Ограничение частоты уменьшает частоту выполнения и лучше всего подходит для прокрутки и перетаскивания. Используйте реализации Lodash, сохранённые в объектах ссылок, и всегда отменяйте их при размонтировании компонента.

Часто задаваемые вопросы

Урок «Зачем нужны debounce и throttle в интерфейсах» бесплатный?

Да — полный текст урока «Зачем нужны debounce и throttle в интерфейсах» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Зачем нужны debounce и throttle в интерфейсах»?

Разберитесь в цене необработанных ограничений частоты для обработчиков нажатий клавиш, прокрутки и изменения размера, а также узнайте, когда применять каждое решение Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Зачем нужны debounce и throttle в интерфейсах»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужны debounce и throttle в интерфейсах
  2. Создание пользовательского хука useDebounce
  3. Создание пользовательского хука useThrottle
  4. Практическое применение: поиск, прокрутка, изменение размера
← Назад к React Academy