100 no PageSpeed com WebGL ao vivo, e o pequeno portão por trás disso
O site do nosso estúdio exibe capas de jogos ao vivo, desenhadas com WebGL, e ainda tira 100 nas quatro categorias do PageSpeed Insights, no celular e no computador. Uma das mudanças que nos levaram até lá agora é um pequeno pacote open source: webgl-gate.
O Lighthouse testa o celular na CPU
O PageSpeed Insights mede páginas móveis no SwiftShader, um rasterizador que desenha WebGL no processador em vez da placa de vídeo. Muitas máquinas virtuais, áreas de trabalho remotas e navegadores com aceleração de hardware desligada fazem o mesmo. Ali uma cena WebGL não é apenas lenta: só baixar e analisar o código já consome tempo da thread principal, e o Total Blocking Time mostra isso.
Nosso site redesenhado começou com 78 no celular, e a maior imagem aparecia após 4,2 segundos.
O que mudamos
- CSS crítico embutido no HTML, para que nada bloqueie a primeira pintura.
- WebGL só onde uma GPU de verdade desenha a página; nos outros casos, a página mostra arte estática e nem baixa o PixiJS.
- Capas AVIF responsivas: celulares recebem imagens de 720 pixels, cerca de três vezes mais leves.
- As capturas de tela dos jogos esperam a capa principal carregar.
O celular chegou a 100: maior imagem em 1,7 segundo, Total Blocking Time de 0 ms e nenhum deslocamento de layout. No computador também é 100, com a maior imagem em 0,4 segundo.
Como o portão decide
O portão cria um contexto WebGL descartável, lê o nome do renderizador e procura por SwiftShader, llvmpipe, softpipe e Basic Render. A flag failIfMajorPerformanceCaveat sozinha não basta: nos nossos testes, o Chrome headless no SwiftShader ainda entrega um contexto com ela ativada.
O número que nos surpreendeu
Numa GPU de verdade, a verificação leva 10–24 ms. No SwiftShader, criar esse primeiro contexto levou 1,4–1,7 segundo da thread principal. A verificação é cara justamente onde a resposta é não. Por isso o webgl-gate espera a página carregar e o navegador ficar ocioso antes de perguntar, e nunca fica no caminho crítico.
Como usar
Instale pelo npm e carregue a cena apenas numa GPU de verdade. Na CPU o import nunca é chamado, então o bundle nunca é baixado.
npm i webgl-gateimport { loadIfFastWebGL } from 'webgl-gate';
const scene = await loadIfFastWebGL(() => import('./scene'));
if (scene) scene.mount(canvas);Há também um hook para React, useFastWebGL, e receitas prontas para Next.js, three.js, React Three Fiber, Vue, Svelte e MapLibre. O núcleo tem menos de 1 kB.
O que ele não faz
Ele responde a uma única pergunta: GPU ou não. Se você precisa saber quão potente é a GPU, o detect-gpu da pmndrs classifica GPUs por pontuações de benchmark. O veredito ainda não fica salvo entre visitas: uma resposta guardada poderia durar mais que o hardware que descreve.