В чём разница между debounce и throttle и где их применяют?
Производительность в JS
Debounce откладывает вызов функции, пока события не прекратятся на заданное время, а throttle пропускает вызовы не чаще одного раза за интервал. Оба приёма сокращают число тяжёлых вызовов на частых событиях.
Debounce
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}Каждый новый вызов сбрасывает таймер, поэтому функция сработает один раз — после паузы в delay мс.
Throttle
function throttle(fn, interval) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last >= interval) {
last = now;
fn.apply(this, args);
}
};
}Функция вызывается сразу, затем игнорируется до конца интервала.
Где что применять
- debounce: поиск по мере ввода, автосохранение черновика, пересчёт после
resize, когда нужно только финальное значение. - throttle:
scroll,mousemove, перетаскивание, отправка аналитики прокрутки — результат нужен регулярно, но не на каждое событие.
Нюансы
fn.apply(this, args)сохраняет контекст и аргументы исходного вызова.- Debounce не отменяет уже отправленный запрос: для поиска к нему добавляют
AbortController. - В React обёртку создают один раз (
useMemo,useRef), иначе каждый рендер получает новый таймер и debounce не работает.
Коротко для собеседования
Debounce выполняет функцию один раз после паузы в событиях, throttle — не чаще раза за интервал. Debounce подходит для ввода и финальных значений, throttle — для непрерывных событий вроде скролла.