Texto longo, leia o resumo
- O Chrome 60 reduz o tempo de carregamento diminuindo a frequência de eventos, melhorando a consistência do tempo de frame.
- O método
getCoalescedEvents()
, introduzido no Chrome 58, oferece a mesma quantidade de informações de eventos que você já tinha.
Oferecer uma experiência do usuário tranquila é importante para a Web. O tempo entre o recebimento de um evento de entrada e o momento em que os recursos visuais são atualizados é importante, e geralmente fazer menos trabalho é importante. Nas últimas versões do Chrome, reduzimos a latência de entrada nesses dispositivos.
Para melhorar a fluidez e o desempenho, no Chrome 60, estamos fazendo uma mudança que faz com que esses eventos ocorram com uma frequência menor, aumentando a granularidade das informações fornecidas. Assim como quando o Jelly Bean foi lançado e trouxe o Choreographer, que alinha a entrada no Android, estamos trazendo a entrada alinhada ao frame para a Web em todas as plataformas.
Mas às vezes você precisa de mais eventos. No
Chrome 58, implementamos
um método chamado
getCoalescedEvents()
, que
permite que seu aplicativo recupere o caminho completo do ponteiro mesmo quando
ele recebe menos eventos.
Vamos falar primeiro sobre a frequência de eventos.
Como diminuir a frequência de eventos
Vamos entender alguns conceitos básicos: as telas sensíveis ao toque fornecem entrada de 60 a 120 Hz, e os mouses geralmente fornecem entrada de 100 Hz (mas podem variar até 2.000 Hz). No entanto, a taxa de atualização típica de um monitor é de 60 Hz. O que isso significa? Isso significa que recebemos entradas em uma taxa mais alta do que a taxa de atualização da tela. Vamos analisar uma linha do tempo de desempenho das ferramentas do desenvolvedor para um app de pintura de tela simples.
Na imagem abaixo, com a entrada alinhada a requestAnimationFrame()
desativada, é possível ver vários blocos de processamento por frame com um tempo de frame inconsistente.
Os pequenos blocos amarelos indicam o teste de acerto para coisas como o destino do
evento DOM, o envio do evento, a execução do JavaScript, a atualização do nó
sobreposto e possivelmente o recalculo do layout e dos estilos.

Por que estamos fazendo um trabalho extra que não causa atualizações visuais? O ideal é
não fazer nenhum trabalho que não beneficie o usuário. A partir do
Chrome 60, o pipeline de entrada vai atrasar o envio de eventos contínuos
(wheel
,
mousewheel
,
touchmove
,
pointermove
,
mousemove
) e
enviá-los logo antes do
callback requestAnimationFrame()
ocorrer. Na imagem abaixo (com o recurso ativado), você vê um tempo de frame mais
consistente e menos tempo de processamento de eventos.
Estamos realizando um experimento com esse recurso ativado nos canais Canary e Dev e descobrimos que realizamos 35% menos testes de hit, o que permite que a linha de execução principal esteja pronta para ser executada com mais frequência.
Uma observação importante que os desenvolvedores da Web precisam saber é que qualquer evento
discreto (como keydown
,
keyup
,
mouseup
,
mousedown
,
touchstart
,
touchend
) que
ocorre será enviado imediatamente com todos os eventos pendentes, preservando
a ordem relativa. Com esse recurso ativado, grande parte do trabalho é
simplificada no fluxo normal de loop de eventos, oferecendo um intervalo de entrada consistente. Isso traz eventos contínuos
em conformidade com os eventos scroll
e resize
,
que já foram simplificados no fluxo de repetição de eventos no Chrome.

Descobrimos que a grande maioria dos aplicativos que consomem esses eventos não usa a frequência mais alta. O Android já alinha eventos há vários anos, então nada é novo, mas os sites podem ter eventos menos granulares em plataformas para computador. Sempre houve um problema com linhas de execução principais instáveis que causam interrupções na fluidez da entrada, o que significa que você pode notar saltos na posição sempre que o aplicativo estiver trabalhando, o que torna impossível saber como o ponteiro passou de um ponto para outro.
O método getCoalescedEvents()
Como eu disse, há raros cenários em que o aplicativo prefere saber
o caminho completo do ponteiro. Para corrigir o caso em que você vê saltos grandes e
a frequência reduzida de eventos, no Chrome 58,
lançamos uma extensão para eventos de ponteiro chamada
getCoalescedEvents()
. Confira abaixo um exemplo de como o jank na linha de execução principal é oculto do
aplicativo se você usar essa API.

Em vez de receber um único evento, você pode acessar a matriz de eventos históricos que o causou. O Android, o iOS e o Windows têm APIs muito semelhantes nos SDKs nativos, e estamos expondo uma API semelhante para a Web.
Normalmente, um app de desenho pode ter desenhado um ponto observando os deslocamentos no evento:
window.addEventListener("pointermove", function(event) {
drawPoint(event.pageX, event.pageY);
});
Esse código pode ser facilmente alterado para usar a matriz de eventos:
window.addEventListener("pointermove", function(event) {
var events = 'getCoalescedEvents' in event ? event.getCoalescedEvents() : [event];
for (let e of events) {
drawPoint(e.pageX, e.pageY);
}
});
Nem todas as propriedades nos eventos agrupados são preenchidas. Como os
eventos agrupados não são realmente enviados, mas apenas acompanham o percurso, eles
não são testados. Alguns campos, como currentTarget
e eventPhase
, terão
valores padrão. Chamar métodos relacionados ao envio, como stopPropagation()
ou preventDefault()
, não terá efeito no evento pai.