Se você já lidou com eventos que disparam inúmeras vezes em milissegundos, como por exemplo, digitar em um campo de busca ou rolar uma página, provavelmente já sentiu o impacto de uma função sendo chamada com muita frequência. O resultado? Travamentos, lentidão e uma aplicação que parece mal otimizada.
São nesses casos que entra o Debounce, que é uma técnica simples, mas muito útil, para melhorar o desempenho da sua aplicação e reduzir chamadas desnecessárias.

O que é Debounce?
Debounce é uma forma de “segurar” a execução de uma função até que o usuário pare de realizar uma determinada ação.
Em outras palavras, ele garante que uma função só será chamada depois de um pequeno intervalo sem novas execuções.
Vamos imaginar um campo de busca que dispara uma requisição a cada tecla digitada. Se o usuário digita “javascript”, isso pode gerar 10 requisições para o servidor, uma por letra. Com debounce, você espera o usuário terminar de digitar – e então dispara apenas uma requisição.

Exemplo prático: debounce em sua forma pura (sem bibliotecas)
A implementação mais comum e didática usa setTimeout e clearTimeout.
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => func.apply(this, args), delay);
};
}Vamos usar isso em um campo de busca:
const input = document.querySelector("#search");
const handleSearch = debounce((event) => {
console.log("Buscando por:", event.target.value);
}, 500);
input.addEventListener("input", handleSearch);O que está acontecendo aqui:
- Cada vez que o usuário digita, o
setTimeouté reiniciado. - Só quando o usuário para de digitar por 500ms, a função realmente roda.
- Assim, você evita chamadas repetidas e melhora o desempenho.
Onde o Debounce é útil
Debounce é essencial quando você quer reagir apenas depois de o usuário parar de interagir.
Alguns exemplos práticos:
- Campos de busca que fazem requisições para APIs;
- Scroll ou resize da janela (para evitar cálculos a cada pixel rolado);
- Validação de formulários enquanto o usuário digita;
- Reajustes de layout após o redimensionamento da tela.
Implementando Debounce com React Hooks
Em aplicações React, é comum encapsular o debounce em um Hook reutilizável. Este é um exemplo simples de um useDebounce:
import { useEffect, useState } from "react";
export function useDebounce(value, delay = 500) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}Uso prático:
function SearchInput() {
const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500);
useEffect(() => {
if (debouncedQuery) {
console.log("Buscando:", debouncedQuery);
// fetch(`/api/search?q=${debouncedQuery}`)
}
}, [debouncedQuery]);
return (
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Digite algo..."
/>
);
}O useDebounce evita que a função de busca seja executada a cada tecla digitada. Ela só dispara quando o usuário para de digitar.
Debounce vs Throttle: Qual a diferença?
Este é um ponto muito importante, pois apesar de serem parecidos na implementação, atuam em finalidades diferentes.
- Debounce: executa depois que o usuário para de interagir.
- Throttle: executa em intervalos fixos, mesmo que o evento continue disparando.
Use debounce quando o foco for reduzir chamadas até a última interação (ex: busca, resize).
Use throttle quando quiser limitar a frequência de execução (ex: scroll contínuo, tracking de mouse).
Cuidados e desvantagens
Debounce é ótimo, mas pode existem alguns pontos que não podem ser negligenciados:
- Pode atrasar a execução em situações onde a resposta precisa ser imediata;
- O tempo (
delay) precisa ser calibrado com cuidado – muito curto e não resolve, muito longo e gera lentidão percebida; - Em componentes React, o uso incorreto pode causar re-renderizações desnecessárias ou perda de estado.
Conclusão
O debounce é uma técnica simples, mas essencial para aplicações frontend. Ele melhora o desempenho, economiza recursos e proporciona uma experiência mais fluida para o usuário.
Comece implementando com setTimeout e clearTimeout, e conforme evoluir, crie Hooks personalizados ou utilitários reutilizáveis no seu projeto. É uma daquelas otimizações pequenas que fazem toda a diferença.


Deixe um comentário