Skip to main content

Що робить "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

ХарактеристикаDebounceThrottle
Коли викликаєтьсяПісля паузиКожні N мс
Частота викликуМаксимум 1 раз після "затишшя"Регулярно, але не частіше N мс
Типовий випадокinput, resize, searchscroll, mousemove, infinite scroll
Приклад поведінкиПостріл один раз після завершення дійПостріл кожні N мс, поки дії тривають

Підсумок

Що робитьНавіщо потрібно
Відкладає виклик функції до завершення серії подійЗапобігає надмірним викликам
Знижує навантаження на CPU і мережуПідвищує чуйність і стабільність
Простий у реалізації та інтеграціїПрацює з будь-якими обробниками подій
Часто використовується разом з throttleДля різних сценаріїв

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.