Os gerenciadores de entrada são uma possível causa de problemas de desempenho nos apps, pois podem bloquear a conclusão de quadros e provocar atividades adicionais e desnecessárias de layout.
Os gerenciadores de entrada são uma possível causa de problemas de desempenho nos apps, pois podem bloquear a conclusão de quadros e provocar atividades de layout adicionais e desnecessárias.
Resumo
- Evite gerenciadores de entrada com execução longa. Eles podem bloquear a rolagem.
- Não faça mudanças de estilo nos gerenciadores de entrada.
- Atrase seus gerenciadores: armazene valores de evento e lide com as mudanças de estilo no próximo retorno de chamada de requestAnimationFrame.
Evite gerenciadores de entrada com execução longa
No caso mais rápido possível, quando um usuário interage com a página, o thread compositor da página pode pegar a entrada de toque do usuário e simplesmente mover o conteúdo. Isso não exige trabalho do encadeamento principal, onde são executados JavaScript, layout, estilos e coloração.
No entanto, se você anexar um gerenciador de entrada, como touchstart
, touchmove
ou touchend
, o thread do compositor vai precisar aguardar o término da execução do gerenciador, porque você pode chamar preventDefault()
e impedir que a rolagem por toque ocorra. Mesmo que você não chame preventDefault()
, o compositor precisa esperar, e como a rolagem do usuário é bloqueada, pode resultar em oscilação e quadros ausentes.
Resumindo, verifique se todos os gerenciadores de entrada usados são executados rapidamente e permitem que o compositor faça seu trabalho.
Evite mudanças de estilo nos gerenciadores de entrada
Os gerenciadores de entrada, como os usados na rolagem e no toque, são programados para serem executados logo antes de qualquer callback requestAnimationFrame
.
Se você fizer uma mudança visual dentro de um desses gerenciadores, haverá mudanças de estilo pendentes no início do requestAnimationFrame
. Se ler nesse momento as propriedades visuais no início do callback requestAnimationFrame, como o conselho em Evite layouts grandes, complexos e extravagantes, você acionará um layout síncrono forçado.
Atrase os gerenciadores de rolagem
A solução para ambos os problemas acima é a mesma: retarde sempre as alterações 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);
Esse retardo oferece o benefício adicional de manter os gerenciadores de entrada leves, o que é muito bom porque ações como rolagem ou toque não são mais bloqueadas em código com alto custo computacional!