Что такое debounce?
Вопрос
Что такое debounce и когда его применяют?
Короткий ответ
Debounce — это техника, которая откладывает вызов функции до тех пор, пока не пройдёт заданная пауза без новых вызовов: каждый новый вызов сбрасывает таймер заново, и функция реально выполняется только один раз — после того как события перестали приходить.
Подробный ответ
Debounce используют, чтобы не выполнять дорогую операцию (запрос к серверу, сложный рендер, валидацию) на каждое срабатывание частого события — ввод текста, resize окна, скролл. Вместо этого функция выполняется один раз, когда пользователь "успокоился".
Реализуется через setTimeout и замыкание, которое хранит идентификатор таймера между вызовами:
- При каждом вызове debounced-функции предыдущий таймер отменяется (
clearTimeout). - Ставится новый таймер на
delayмс. - Если за это время новых вызовов не было — оригинальная функция выполняется.
Debounce стоит отличать от throttle: throttle гарантирует, что функция выполняется не чаще, чем раз в delay мс (равномерно, независимо от того, прекратился поток событий или нет), а debounce откладывает выполнение до полной паузы.
Пример
function debounce(fn, delay) {
let timeoutId
return function (...args) {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => fn.apply(this, args), delay)
}
}
const input = document.querySelector('#search')
const handleSearch = debounce((event) => {
fetch(`/api/search?q=${event.target.value}`)
}, 300)
input.addEventListener('input', handleSearch)
// Запрос уйдёт на сервер только через 300мс после того,
// как пользователь перестал печатать
Дополнительные вопросы
- Чем debounce отличается от throttle и когда что использовать?
- Как реализовать debounce с "немедленным" первым вызовом (leading edge)?
- Как debounce/throttle реализованы в популярных библиотеках (lodash, VueUse)?