Що робить "debounce"?
Що таке debounce
Debounce (від англ. to debounce - "усувати дрижання") - це прийом, який обмежує частоту виклику функції, змушуючи її виконуватися лише після того, як події припинилися на заданий час.
Простіше кажучи:
- "Почекай N мілісекунд після останнього виклику, і лише тоді виконай функцію."
Приклад без debounce
javascript
window.addEventListener('resize', () => {
console.log('Зміна розміру вікна');
});Якщо користувач змінює розмір вікна - ця подія може спрацьовувати десятки разів на секунду, що створює величезне навантаження на код усередині обробника.
Приклад з debounce
javascript
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer); // скидаємо попередній таймер
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const handleResize = debounce(() => {
console.log('Розмір вікна змінився (після паузи)');
}, 300);
window.addEventListener('resize', handleResize);Тепер:
- якщо користувач продовжує змінювати розмір -> функція не викликається;
- щойно він зупинився (на >= 300 мс) -> функція виконується один раз.
Де використовується debounce
| Сценарій | Чому потрібен |
|---|---|
scroll, resize, mousemove | Ці події відбуваються десятки разів на секунду |
input (пошук, фільтр) | Щоб не робити API-запит на кожну літеру |
window.onresize | Щоб не перераховувати layout занадто часто |
| Автозбереження форм | Зберігати лише після паузи в наборі тексту |
| Live Search | Надсилати запит лише після того, як користувач перестав друкувати |
Приклад з пошуком
javascript
const input = document.querySelector('#search');
const handleInput = debounce(async (event) => {
const query = event.target.value;
const results = await fetch(`/api/search?q=${query}`).then(res => res.json());
console.log(results);
}, 500);
input.addEventListener('input', handleInput);Користувач вводить "frontend", і запит піде лише один раз,
через 500 мс після того, як він закінчить введення.
Варіації debounce
1. Лише "після паузи" (класичний)
- функція виконується один раз після того, як потік подій закінчився.
2. З негайним викликом (immediate)
- функція виконується одразу при першій події,
але потім ігнорує наступні, поки не мине
delay.
javascript
function debounce(fn, delay, immediate = false) {
let timer;
return function (...args) {
const callNow = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
if (!immediate) fn.apply(this, args);
}, delay);
if (callNow) fn.apply(this, args);
};
}Debounce vs Throttle
| Характеристика | Debounce | Throttle |
|---|---|---|
| Коли викликається | Після паузи | Кожні N мс |
| Частота виклику | Максимум 1 раз після "затишшя" | Регулярно, але не частіше N мс |
| Типовий випадок | input, resize, search | scroll, mousemove, infinite scroll |
| Приклад поведінки | Постріл один раз після завершення дій | Постріл кожні N мс, поки дії тривають |
Підсумок
| Що робить | Навіщо потрібно |
|---|---|
| Відкладає виклик функції до завершення серії подій | Запобігає надмірним викликам |
| Знижує навантаження на CPU і мережу | Підвищує чуйність і стабільність |
| Простий у реалізації та інтеграції | Працює з будь-якими обробниками подій |
| Часто використовується разом з throttle | Для різних сценаріїв |
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.