Descubra o que é o atraso de entrada e aprenda técnicas para reduzi-lo e acelerar a interatividade.
As interações na Web são complicadas, com todos os tipos de atividade ocorrendo no navegador para impulsioná-las. No entanto, todas elas têm em comum o fato de que geram algum atraso de entrada antes que os callbacks de evento comecem a ser executados. Neste guia, você vai aprender o que é o atraso de entrada e o que pode fazer para minimizá-lo, de modo que as interações do seu site sejam executadas mais rapidamente.
O que é latência na entrada?
O atraso de entrada é o período que começa quando o usuário interage pela primeira vez com uma página, como tocar em uma tela, clicar com o mouse ou pressionar uma tecla, até o momento em que os callbacks de evento da interação começam a ser executados. Toda interação começa com algum atraso de entrada.
Uma parte do atraso de entrada é inevitável: o sistema operacional sempre leva algum tempo para reconhecer um evento de entrada e transmiti-lo ao navegador. No entanto, essa parte do atraso de entrada geralmente não é perceptível, e há outras coisas que acontecem na própria página que podem tornar os atrasos de entrada longos o suficiente para causar problemas.
Como pensar sobre o atraso de entrada
De modo geral, é recomendável manter cada parte de uma interação o mais curta possível para que seu site tenha a melhor chance de atingir o limite "bom" da métrica Interaction to Next Paint (INP), independentemente do dispositivo do usuário. Manter o atraso de entrada sob controle é apenas uma parte do cumprimento desse limite.
Portanto, é recomendável buscar o menor atraso de entrada possível para atingir o limite "bom" da INP. No entanto, não é possível eliminar totalmente os atrasos de entrada. Contanto que você evite o trabalho excessivo na linha de execução principal enquanto os usuários tentam interagir com sua página, o atraso de entrada será baixo o suficiente para evitar problemas.
Como minimizar o atraso de entrada
Como já dissemos, um pouco de atraso de entrada é inevitável, mas, por outro lado, parte dele pode ser evitada. Confira algumas considerações se você estiver com problemas de atraso de entrada longo.
Evite timers recorrentes que iniciam um trabalho excessivo na linha de execução principal
Há duas funções de timer usadas com frequência em JavaScript que podem contribuir para o atraso de entrada: setTimeout e setInterval. A diferença entre os dois é que setTimeout programa um callback para ser executado após um tempo especificado. setInterval, por outro lado, programa um callback para ser executado a cada n milissegundos de forma contínua ou até que o timer seja interrompido com clearInterval.
setTimeout não é um problema em si. Na verdade, pode ser útil para evitar tarefas longas. No entanto, isso depende de quando o tempo limite ocorre e se o usuário tenta interagir com a página quando o callback de tempo limite é executado.
Além disso, setTimeout pode ser executado em um loop ou de forma recursiva, em que ele age mais como setInterval, mas, de preferência, sem programar a próxima iteração até que a anterior seja concluída. Embora isso signifique que o loop vai ser transferido para a linha de execução principal sempre que setTimeout for chamado, é preciso garantir que o callback não acabe fazendo um trabalho excessivo.
setInterval executa um callback em um intervalo e, portanto, tem muito mais chances de atrapalhar as interações. Isso ocorre porque, ao contrário de uma única instância de uma chamada setTimeout, que é um callback único que pode atrapalhar uma interação do usuário, a natureza recorrente de setInterval aumenta muito a probabilidade de que ela atrapalhe uma interação, aumentando o atraso de entrada dela.
setInterval anterior que contribui para o atraso de entrada, conforme mostrado no painel de desempenho do Chrome DevTools. O atraso de entrada adicionado faz com que os callbacks de evento da interação sejam executados mais tarde do que o normal.
Se os timers estiverem ocorrendo no código próprio, você terá controle sobre eles. Avalie se você precisa deles ou faça o possível para reduzir o trabalho neles. No entanto, os timers em scripts de terceiros são uma história diferente. Muitas vezes, você não tem controle sobre o que um script de terceiros faz, e corrigir problemas de desempenho em códigos de terceiros geralmente envolve trabalhar com as partes interessadas para determinar se um determinado script de terceiros é necessário e, em caso afirmativo, estabelecer contato com um fornecedor de scripts de terceiros para determinar o que pode ser feito para corrigir problemas de desempenho que eles podem causar no seu site.
Evitar tarefas longas
Uma maneira de reduzir os atrasos de entrada longos é evitar tarefas longas. Quando há um trabalho excessivo na linha de execução principal que a bloqueia durante as interações, isso aumenta o atraso de entrada antes que as tarefas longas tenham a chance de terminar.
Além de minimizar a quantidade de trabalho em uma tarefa (e você deve sempre se esforçar para fazer o mínimo possível na linha de execução principal), é possível melhorar a capacidade de resposta à entrada do usuário dividindo tarefas longas.
Cuidado com a sobreposição de interações
Uma parte particularmente desafiadora da otimização da INP pode ser se você tiver interações que se sobrepõem. A sobreposição de interações significa que, depois de interagir com um elemento, você faz outra interação com a página antes que a interação inicial tenha tido a chance de renderizar o próximo frame.
As fontes de sobreposição de interações podem ser tão simples quanto os usuários fazendo muitas interações em um curto período. Isso pode ocorrer quando os usuários digitam em campos de formulário, em que muitas interações de teclado podem ocorrer em um período muito curto. Se o trabalho em um evento de tecla for especialmente caro, como no caso comum de campos de preenchimento automático em que as solicitações de rede são feitas para um back-end, você tem algumas opções:
- Considere remover o debounce das entradas para limitar o número de vezes que um callback de evento é executado em um determinado período.
- Use
AbortControllerpara cancelar solicitaçõesfetchde saída para que a linha de execução principal não fique congestionada ao processar callbacksfetch. Observação: a propriedadesignalde uma instânciaAbortControllertambém pode ser usada para cancelar eventos.
Outra fonte de aumento do atraso de entrada devido a interações sobrepostas podem ser animações caras. Em particular, as animações em JavaScript podem disparar muitas chamadas requestAnimationFrame, o que pode atrapalhar as interações do usuário. Para contornar isso, use animações CSS sempre que possível para evitar o enfileiramento de frames de animação potencialmente caros. No entanto, se você fizer isso, evite animações não compostas para que as animações sejam executadas principalmente nas linhas de execução da GPU e do compositor, e não na linha de execução principal.
Conclusão
Embora os atrasos de entrada possam não representar a maior parte do tempo que as interações levam para serem executadas, é importante entender que cada parte de uma interação leva um tempo que você pode reduzir. Se você observar um atraso de entrada longo, há oportunidades para reduzi-lo. Evitar callbacks de timer recorrentes, dividir tarefas longas e estar ciente de possíveis sobreposições de interação pode ajudar a reduzir o atraso de entrada, levando a uma interatividade mais rápida para os usuários do seu site.