Os processadores de entrada podem causar problemas de desempenho nos apps, porque podem impedir a conclusão de frames e causar trabalho de layout adicional e desnecessário.
Os processadores de entrada podem causar problemas de desempenho nos apps, porque podem impedir a conclusão de frames e causar trabalhos de layout adicionais e desnecessários.
Resumo
- Evite processadores de entrada de longa duração. Eles podem bloquear a rolagem.
- Não faça mudanças de estilo em manipuladores de entrada.
- Debounce seus gerenciadores, armazene valores de eventos e lide com mudanças de estilo no próximo callback de requestAnimationFrame.
Evitar processadores de entrada de longa duração
No caso mais rápido possível, quando um usuário interage com a página, a linha de execução do compositor dela pode usar a entrada de toque do usuário e simplesmente mover o conteúdo. Isso não exige trabalho da linha de execução principal, em que JavaScript, layout, estilos ou pintura são feitos.

No entanto, se você anexar um gerenciador de entrada, como touchstart
, touchmove
ou touchend
, a linha de execução do compositor terá que aguardar a conclusão da execução desse gerenciador, porque você pode chamar preventDefault()
e interromper a rolagem por toque. Mesmo que você não chame preventDefault()
, o compositor precisa esperar, e, por isso, a rolagem do usuário é bloqueada, o que pode resultar em frames irregulares e perdidos.

Em resumo, você precisa garantir que todos os manipuladores de entrada executados sejam executados rapidamente e permitam que o compositor faça o trabalho.
Evite mudanças de estilo em manipuladores de entrada
Os gerenciadores de entrada, como os de rolagem e toque, são programados para serem executados antes de qualquer callback requestAnimationFrame
.
Se você fizer uma mudança visual em um desses manipuladores, no início do requestAnimationFrame
, haverá mudanças de estilo pendentes. Se você então ler propriedades visuais no início do callback requestAnimationFrame, como sugere o conselho em Evitar layouts grandes e complexos e o thrashing de layout, você vai acionar um layout síncrono forçado.

Debounce seus manipuladores de rolagem
A solução para os dois problemas acima é a mesma: sempre debique as mudanças visuais para o próximo callback requestAnimationFrame
:
function onScroll (evt) {
// Store the scroll value for laterz.
lastScrollY = window.scrollY;
// Prevent multiple rAF callbacks.
if (scheduledAnimationFrame)
return;
scheduledAnimationFrame = true;
requestAnimationFrame(readAndUpdatePage);
}
window.addEventListener('scroll', onScroll);
Isso também tem o benefício adicional de manter os gerenciadores de entrada leves, o que é ótimo porque agora você não está bloqueando coisas como rolagem ou toque em um código com custo computacional alto.