Debounce и throttle — это два ключевых приёма оптимизации производительности при обработке событий в веб-приложениях. Они позволяют контролировать частоту вызовов функций, что особенно важно при работе с событиями ввода, прокрутки или ресайза, где частота вызова может достигать сотен раз в секунду.
Debounce — это техника, при которой функция вызывается только после того, как событие перестало происходить в течение определённого времени. Основная цель — сгладить резкие, часто повторяющиеся вызовы функции и выполнить её только после «паузы».
function debounce(func, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => func.apply(this, args), delay);
};
}
// Пример использования:
const handleResize = debounce(() => {
console.log('Resize завершён');
}, 300);
window.addEventListener('resize', handleResize);
Ключевые моменты debounce:
Throttle ограничивает частоту вызова функции. В отличие от debounce, функция вызывается регулярно, но не чаще установленного интервала времени. Используется, когда важно реагировать на событие с определённой периодичностью, а не только после завершения серии вызовов.
function throttle(func, limit) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= limit) {
lastCall = now;
func.apply(this, args);
}
};
}
// Пример использования:
const handleScroll = throttle(() => {
console.log('Scroll событие обработано');
}, 200);
window.addEventListener('scroll', handleScroll);
Ключевые моменты throttle:
| Параметр | Debounce | Throttle |
|---|---|---|
| Поведение | Вызывает функцию после паузы | Вызывает функцию с фиксированным интервалом |
| Идеальное применение | Ввод текста, ресайз окна, фильтры | Скролл, drag & drop, события мыши |
| Основной эффект | Сглаживание резких повторений | Ограничение частоты вызова |
При работе с библиотекой Naive UI debounce и throttle часто применяются для оптимизации взаимодействия с компонентами ввода и таблицами данных.
<template>
<n-input v-model="searchQuery" @input="debouncedSearch" placeholder="Поиск..." />
</template>
<script setup>
import { ref } from 'vue';
import { debounce } from 'lodash';
const searchQuery = ref('');
const performSearch = (query) => {
console.log('Поиск по запросу:', query);
};
const debouncedSearch = debounce(() => performSearch(searchQuery.value), 300);
</script>
Здесь debounce позволяет не вызывать функцию поиска при каждом нажатии клавиши, а только после паузы в наборе текста.
<template>
<div @scroll="throttledScroll" style="height: 300px; overflow: auto;">
<n-list>
<n-list-item v-for="i in 100" :key="i">Элемент {{ i }}</n-list-item>
</n-list>
</div>
</template>
<script setup>
import { throttle } from 'lodash';
const handleScroll = (event) => {
console.log('Позиция скролла:', event.target.scrollTop);
};
const throttledScroll = throttle(handleScroll, 200);
</script>
Использование throttle предотвращает чрезмерное срабатывание обработчика скролла, снижая нагрузку на рендеринг компонентов.
delay важно
исходя из сценария: для ввода текста достаточно 200–500 мс, для ресайза
окна — 300–400 мс.limit подбирается
по частоте обновления UI: для плавного скролла — 100–200 мс, для drag
& drop — 16–50 мс (≈60 FPS).n-input, n-select) —
часто оборачиваются в debounce для оптимизации поиска
или автозаполнения.n-list,
n-table) — используют throttle для
обработки событий scroll и resize, чтобы поддерживать плавную
производительность.Debounce и throttle — базовые инструменты оптимизации производительности веб-приложений, которые в сочетании с Naive UI позволяют создавать отзывчивые, плавные интерфейсы без лишней нагрузки на браузер. Правильное применение этих техник делает взаимодействие с компонентами быстрым и предсказуемым даже при интенсивной работе с DOM.