Como otimizar performance 3D e renderização Canvas no navegador
Cenas Canvas e WebGL complexas costumam começar suaves e desandar assim que o número de objetos cresce. A boa notícia: a maior parte dos gargalos de performance no navegador é previsível e tem correção direta. Aqui está o checklist que uso em produção.
1. Meça antes de otimizar
Abra o painel Performance do DevTools e grave 5 segundos de execução real. Procure por barras longas em Scripting, Rendering e Painting — cada uma aponta para um tipo diferente de problema. Otimizar sem esse diagnóstico costuma resolver o sintoma errado.
2. Um único loop de animação
Evite múltiplos setInterval ou requestAnimationFrame espalhados pelo código. Centralize tudo em um único loop que atualiza estado e desenha em sequência — isso evita chamadas de desenho duplicadas no mesmo frame e mantém o timing consistente com o refresh rate da tela.
3. Object pooling em vez de recriação
Criar e descartar milhares de objetos por segundo (partículas, projéteis, nós) sobrecarrega o garbage collector e gera engasgos periódicos. Mantenha um pool de objetos reutilizáveis e apenas "resete" seus atributos ao invés de instanciar novos:
// Pool simples de partículas
const pool = [];
function getParticle() {
return pool.pop() || { x:0, y:0, vx:0, vy:0, life:0 };
}
function releaseParticle(p) {
pool.push(p);
}
4. Culling: não desenhe o que não aparece
Antes de chamar draw() em cada objeto, verifique se ele está dentro da área visível (viewport ou frustum, no caso 3D). Ignorar elementos fora de tela costuma ser a otimização de maior impacto em cenas com muitos nós.
5. Cuidado com o devicePixelRatio
Em telas de alta densidade, renderizar no devicePixelRatio nativo (2x, 3x) multiplica o número de pixels processados. Em cenas pesadas, limitar esse valor a 1.5 ou usar resolução dinâmica conforme o FPS medido evita quedas bruscas em dispositivos móveis.
6. Separe camadas estáticas de camadas dinâmicas
Elementos que raramente mudam (fundo, grade, UI fixa) não precisam ser redesenhados a cada frame. Use um <canvas> secundário ou um buffer offscreen para o conteúdo estático e componha as camadas apenas quando necessário.
7. Evite layout thrashing fora do canvas
Se a cena interage com elementos DOM ao redor, alternar leitura e escrita de propriedades de layout (offsetWidth, depois style.left, depois offsetWidth de novo) força recomputação forçada de layout a cada frame. Agrupe leituras e escritas em lotes separados.
Resultado esperado
Aplicando esses seis pontos em conjunto — e não isoladamente — é comum sair de cenas instáveis (30–40 FPS com quedas) para 60 FPS estáveis mesmo em milhares de elementos simultâneos, incluindo em hardware modesto.
Precisa de uma experiência 3D ou visualização interativa performática no seu produto? Diagnóstico rápido, sem compromisso.
Solicitar Diagnóstico