Debounce vs Throttle vs useMemo
Debounce atrasa execução. Throttle limita frequência. useMemo cacheia resultado. Casos de uso distintos.
Definição
Debounce: espera X ms após o último evento antes de executar — ideal para inputs de busca (não chama API a cada tecla). Throttle: executa no máximo 1x a cada X ms — ideal para scroll/resize. useMemo: memoriza o resultado de um cálculo enquanto as dependências não mudam — para cálculos pesados durante render, não para eventos assíncronos.
Problema → Solução
Problema
Chamar API a cada keystroke (sem debounce), travar o browser com scroll handler sem throttle, ou recalcular uma lista filtrada a cada render quando o input não mudou.Solução
Debounce para input → API (300-500ms típico). Throttle para scroll/resize (16ms = 60fps). useMemo para filtrar/ordenar listas dentro do render. useTransition para marcar updates pesados como não-urgentes (React 18).Dica de entrevista
Tip
debounce e throttle são para eventos assíncronos/externos. useMemo é para cálculos síncronos dentro do ciclo de render do React. Não use useEffect + setTimeout para debounce — use useRef ou libs como use-debounce.Código
// Debounce para busca com useRef
function SearchInput({ onSearch }) {
const timer = useRef()
const handleChange = (e) => {
clearTimeout(timer.current)
timer.current = setTimeout(() => onSearch(e.target.value), 300)
}
return <input onChange={handleChange} />
}
// Throttle para scroll com passive listener
useEffect(() => {
let last = 0
const handler = () => {
const now = Date.now()
if (now - last < 100) return
last = now
checkScrollPosition()
}
window.addEventListener('scroll', handler, { passive: true })
return () => window.removeEventListener('scroll', handler)
}, [])
// useMemo para cálculo em render
const sorted = useMemo(
() => items.slice().sort((a, b) => a.name.localeCompare(b.name)),
[items]
)Perguntas de entrevista
Q.Como implementar debounce sem libs?▾
A.Com useRef para guardar o timer: const timer = useRef(); no handler, clearTimeout(timer.current) e timer.current = setTimeout(() => call(val), 300). O cleanup no useEffect garante cancelar ao desmontar.
Q.startTransition substitui debounce?▾
A.Para filtros de lista local sim — startTransition prioriza o input e processa o filtro em background. Para chamadas de API não — startTransition não atrasa o request. Debounce ainda é necessário para reduzir requests de rede.
Q.Quando throttle é melhor que debounce?▾
A.Throttle quando quer feedback contínuo mas limitado: scroll infinito, resize handler, tracking de mouse. Debounce quando quer só o valor final: campo de busca, autocomplete, validação de CEP.
Termos relacionados
51/122← →