O que é e para que serve debounce em JavaScript

Uma dica importante de performance em JavaScript quando estamos trabalhando em aplicações web ricas ou as famosas SPAs. O debounce é muito útil e importante no universo JavaScript, por isso confira este texto e os exemplos até o final.

— 5 minutos de leitura

Editar este artigo

Se este conteúdo te ajudar, considere apoiar meu trabalho através do Apoia.se

Quando trabalhamos com o desenvolvimento de aplicações web ricas, aquelas cheias de eventos e trabalhando com requisições HTTP, muitas vezes corremos o risco de disparar diversos eventos de salvamento, atualização de estados e outras funções sem querer que isso aconteça.

Imagine uma função de salvamento automático, onde o usuário digita em um campo de input ou textarea e devemos salvar a palavra ou texto digitados enviando para um servidor. Agora, vamos pensar que este usuário pode digitar uma letra por segundo ou mesmo diversas palavras. Em qual momento a função de salvar deve ser executada?

A problemática permalink

Vamos seguir com o exemplo do textarea que envia o texto para um backend. Vamos utilizar o evento de input para disparar uma função que vai salvar o texto.

No exemplo abaixo temos um textarea com a função de salvamento somente te mostrando a quantidade de vezes em que ela seria executada caso disparemos a requisição HTTP para cada input do usuário.

See the Pen textarea-save by William Oliveira (@uillaz) on CodePen.

Perceba, a quantidade de disparos é muito alta. Isso, pensando em requisições em rede, gera diversos problemas, como:

  • sobrecarga da rede: custos de rede em infraestrutura, lentidão de resposta do servidor devido ao alto processamento de dados e inserção no banco de dados
  • lentidão da interface: devido a quantidade de requisições abertas, o navegador pode começar a funcionar de uma maneira mais lenta
  • erros de inserção dos dados: por conta da quantidade de requisições, se o sistema backend não trabalhar bem, teremos o risco de sobrescrever os dados anteriores por algo incompleto

E isso só pensando bem por cima da quantidade de desafios que podemos enfrentar caso sigamos este fluxo. Para evitar isso, utilizamos uma técnica chamada debounce.

Entendendo debounce permalink

Debounce não é algo novo, utilizamos esta técnica desde a época do nosso querido jQuery (e antes). O processo consiste em evitar que uma função seja chamada muitas vezes seguidas.

Um exemplo de caso onde o debounce seria muito útil e é algo extremamente simples é quando clicamos em um botão enviar (já voltamos para o nosso autosave no textarea).

Se temos um botão que executa uma requisição para alterar um status de registro de verdadeiro para falso, por exemplo, e nosso usuário é uma pessoa ansiosa, não tem muito conhecimento em informática ou mesmo possui alguma deficiência motora, esta pessoa pode clicar várias vezes neste botão, o que chamamos de double-click, executando assim mais que uma chamada para o servidor alterando o registro diversas vezes. Isso gera inconsistência de dados, assim como falta de confiança do usuário em nosso sistema.

Também poderia ser o caso de um infinite-scroll, onde uma requisição acontece quando o usuário rola a página. Caso não controlemos este evento, a requisição vai disparar várias vezes, travando a tela com o processamento para inserção dos dados abaixo dos últimos elementos ou mesmo por problemas de rede.

Utilizando debounce, podemos colocar um timer que será chamado quando o usuário parar de executar o evento e volta a contar caso o usuário não pare.

Pensando em nosso autosave, quando o usuário está digitando, não vamos executar a função. Só vamos chamá-la quando o usuário parar de digitar por 500ms. Isso garante que não vamos executar várias e várias vezes o autosave, assim como não vamos perder o valor digitado corretamente.

Vamos a implementação.

Implementando o debounce em JavaScript puro permalink

Pensando que a nossa função de debounce precisa disparar um timer e depois executar uma função, como no caso do nosso autosave, podemos implementar ela com o simples código abaixo:

function debounce(fn, waitTime) {
let timer = null

return function() {
clearTimeout(timer)
timer = setTimeout(fn, waitTime)
}
}

Agora vamos implementar no nosso textarea com autosave:

See the Pen textarea-autosave-debounce by William Oliveira (@uillaz) on CodePen.

A nossa atenção fica voltada para alinha:

contentElm.addEventListener("input", debounce(autoSave, 500))

Onde estamos colocando um timeout de 500ms quando o usuário digitar no textarea.

Conclusão permalink

Utilizar debounce pode salvar o custo de infraestrutura, pois alto consumo de rede e ficar batendo no servidor o tempo todo não é algo muito legal, além do processamento e, claro, a interface do usuário.

Trabalhando com web, precisamos tomar muito cuidado com performance no navegador, pois o frontend tem um peso muito grande na experiência do usuário e isso pode impactar tanto o seu produto, empresa, quanto a vida de uma pessoa que não consegue realizar uma ação importante no seu app.

Espero que tenha entendido e gostado do conteúdo. Se curtiu, compartilha nas redes sociais.

Photo by Alina Grubnyak on Unsplash

Este conteúdo te ajudou? permalink

Se eu consegui te ajudar, considere contribuir com o meu trabalho através dos links abaixo.

Qualquer valor é muito bem vindo e os apoios começam a partir de 1 real. Apoiar via Apoia.se Apoiar via PicPay Apoiar via PayPal