· javascript de software  · 4 min read

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.

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.

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

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

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

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

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

Back to Blog

Related Posts

View All Posts »

Laços de repetição: for, for...in, for...of

Repetir processos é importante em um software, muitas vezes precisamos executar uma mesma ação e ficaria inviável escrever uma mesma linha de código várias e várias vezes, assim como acessar um dado dentro de um array somente pelo seu indice. Para facilitar nossas vidas existem os laços de repetição.