Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке "debounce" і "throttle" при запитах?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Debounce** і **throttle** - способи контролювати частоту викликів функцій (наприклад, мережевих запитів). **Ключове:** debounce чекає, поки користувач "закінчить", і виконує функцію один раз після паузи, а throttle виконує функцію не частіше, ніж раз на заданий інтервал.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Проблема, яку вони вирішують Якщо користувач швидко друкує в полі пошуку: ```javascript R Re Rea Reac React ``` і при кожному натисканні ти відправляєш запит: ```javascript fetch(`/api/search?q=${query}`); ``` то сервер отримає **5-10 запитів за секунду**, хоча потрібен **лише останній**. Це: - навантажує сервер, - створює зайві `setState` і перемальовування, - може призвести до "гонки" даних (стара відповідь приходить пізніше нової). Тут і допомагають **debounce** і **throttle** - способи *контролювати частоту викликів функцій* (наприклад, мережевих запитів). --- ## 1. **Debounce (усунення тремтіння)** > Debounce - відкладає виконання функції, поки користувач *не перестане викликати її* протягом заданого часу. Тобто: - кожен новий виклик **скидає таймер**; - функція спрацює **лише після паузи**. ### Приклад ```javascript function debounce(fn, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); }; } ``` Використання в React: ```javascript const debouncedSearch = useMemo( () => debounce((value) => fetch(`/api/search?q=${value}`), 500), [] ); <input onChange={(e) => debouncedSearch(e.target.value)} />; ``` Користувач друкує: ```javascript r → re → rea → reac → react ``` -> `fetch()` виконається **один раз**, через 500 мс після останнього вводу. Чудово підходить для: - пошукових запитів; - автокомпліту; - фільтрації при вводі; - перевірки унікальності імені/email при вводі. --- ## 2. **Throttle (обмеження частоти)** > Throttle - дозволяє виконувати функцію **не частіше**, ніж раз на заданий інтервал. Тобто: - перший виклик відбувається одразу; - наступні ігноруються, поки не мине таймер. ### Приклад ```javascript function throttle(fn, delay) { let last = 0; return (...args) => { const now = Date.now(); if (now - last >= delay) { last = now; fn(...args); } }; } ``` Використання в React: ```javascript const throttledScroll = useMemo( () => throttle((event) => console.log(window.scrollY), 200), [] ); useEffect(() => { window.addEventListener('scroll', throttledScroll); return () => window.removeEventListener('scroll', throttledScroll); }, [throttledScroll]); ``` При прокручуванні 60 разів/секунда -> обробник викличеться лише кожні 200 мс (≈5 разів/секунда). Чудово підходить для: - обробників `scroll`, `resize`, `mousemove`; - оновлення позиції, видимості елементів; - "infinite scroll". --- ## Порівняння | Особливість | **Debounce** | **Throttle** | |---|---|---| | Коли виконується | після паузи | через рівні інтервали | | Поведінка при частих викликах | чекає на "тишу" | запускається періодично | | Підходить для | пошуку, вводу тексту | скролу, ресайзу, drag-and-drop | | Кількість викликів | мінімум | обмежена | | UX ефект | "чекає, поки користувач закінчить" | "обмежує частоту оновлень" | --- ## Комбінований приклад (пошук з debounce) ```javascript import { useState, useMemo, useEffect } from "react"; function debounce(fn, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); }; } export function SearchBox() { const [query, setQuery] = useState(""); const [results, setResults] = useState([]); const search = useMemo( () => debounce(async (q) => { const res = await fetch(`/api/search?q=${q}`); setResults(await res.json()); }, 400), [] ); useEffect(() => { if (query) search(query); }, [query, search]); return ( <div> <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Пошук..." /> <ul>{results.map(r => <li key={r.id}>{r.name}</li>)}</ul> </div> ); } ``` Користувач друкує - запит виконується лише після 400 мс "тиші". --- ## Підсумок | Що робить | Як працює | Де використовувати | |---|---|---| | **Debounce** | чекає, поки користувач перестане викликати функцію | пошук, фільтр, валідація при вводі | | **Throttle** | виконує не частіше, ніж кожні X мс | scroll, resize, drag, infinite-scroll | | **Обидва** | захищають від "шторму викликів" і знижують навантаження | підвищують UX і продуктивність | --- ### Коротко: > **Debounce** - "виконай, коли користувач закінчить". > **Throttle** - "виконуй не частіше, ніж раз на N мс". > > Обидва потрібні, щоб не спамити сервер і не блокувати UI зайвими рендерами при частих подіях.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.