100 en PageSpeed con WebGL en vivo, y la pequeña puerta detrás
La web de nuestro estudio muestra portadas de juegos en vivo dibujadas con WebGL y aun así obtiene 100 en las cuatro categorías de PageSpeed Insights, en móvil y en escritorio. Uno de los cambios que nos llevaron hasta ahí es ahora un pequeño paquete de código abierto: webgl-gate.
Lighthouse prueba el móvil en la CPU
PageSpeed Insights mide las páginas móviles en SwiftShader, un rasterizador que dibuja WebGL con el procesador en lugar de la tarjeta gráfica. Muchas máquinas virtuales, escritorios remotos y navegadores con la aceleración por hardware desactivada hacen lo mismo. Allí una escena WebGL no solo va lenta: solo descargar y analizar su código ya consume tiempo del hilo principal, y el Total Blocking Time lo refleja.
Nuestra web rediseñada empezó con 78 en móvil, y la imagen más grande aparecía a los 4,2 segundos.
Qué cambiamos
- CSS crítico incrustado en el HTML, para que nada bloquee el primer pintado.
- WebGL solo donde una GPU real dibuja la página; en el resto, la página muestra arte estático y ni siquiera descarga PixiJS.
- Portadas AVIF adaptables: los móviles reciben imágenes de 720 píxeles, unas tres veces más ligeras.
- Las capturas de los juegos esperan a que cargue la portada principal.
El móvil subió a 100: imagen más grande a 1,7 segundos, Total Blocking Time de 0 ms y sin desplazamientos del diseño. En escritorio también es 100, con la imagen más grande a 0,4 segundos.
Cómo decide la puerta
La puerta crea un contexto WebGL desechable, lee el nombre del renderizador y busca SwiftShader, llvmpipe, softpipe y Basic Render. La opción failIfMajorPerformanceCaveat por sí sola no basta: en nuestras pruebas, Chrome headless con SwiftShader sigue entregando un contexto con ella activada.
El número que nos sorprendió
En una GPU real, la comprobación tarda 10–24 ms. En SwiftShader, crear ese primer contexto llevó 1,4–1,7 segundos del hilo principal. La comprobación es cara justo donde la respuesta es no. Por eso webgl-gate espera a que la página cargue y el navegador quede libre antes de preguntar, y nunca está en la ruta crítica.
Cómo usarlo
Instálalo con npm y carga tu escena solo en una GPU real. En la CPU el import nunca se llama, así que el paquete nunca se descarga.
npm i webgl-gateimport { loadIfFastWebGL } from 'webgl-gate';
const scene = await loadIfFastWebGL(() => import('./scene'));
if (scene) scene.mount(canvas);También hay un hook de React, useFastWebGL, y recetas listas para Next.js, three.js, React Three Fiber, Vue, Svelte y MapLibre. El núcleo pesa menos de 1 kB.
Lo que no hace
Responde a una sola pregunta: GPU o no. Si necesitas saber cuán potente es la GPU, detect-gpu de pmndrs clasifica las GPU por resultados de benchmarks. El veredicto aún no se guarda entre visitas: una respuesta guardada podría sobrevivir al hardware que describe.