100 sur PageSpeed avec du WebGL en direct, et la petite porte derrière
Le site de notre studio affiche des couvertures de jeux animées, dessinées en WebGL, et obtient pourtant 100 dans les quatre catégories de PageSpeed Insights, sur mobile comme sur ordinateur. L’un des changements qui nous y ont menés est désormais un minuscule paquet open source : webgl-gate.
Lighthouse teste le mobile sur le processeur
PageSpeed Insights mesure les pages mobiles avec SwiftShader, un rastériseur qui dessine le WebGL avec le processeur plutôt qu’avec la carte graphique. Beaucoup de machines virtuelles, de bureaux à distance et de navigateurs sans accélération matérielle font de même. Là, une scène WebGL n’est pas seulement lente : le simple téléchargement et l’analyse de son code coûtent du temps au fil principal, et le Total Blocking Time le montre.
Notre site repensé démarrait à 78 sur mobile, et la plus grande image apparaissait après 4,2 secondes.
Ce que nous avons changé
- CSS critique intégré au HTML, pour que rien ne bloque le premier affichage.
- WebGL uniquement là où un vrai GPU dessine la page ; ailleurs, la page affiche une image fixe et ne télécharge même pas PixiJS.
- Couvertures AVIF adaptatives : les téléphones reçoivent des images de 720 pixels, environ trois fois plus légères.
- Les captures des jeux attendent que la couverture principale soit chargée.
Le mobile est passé à 100 : plus grande image à 1,7 seconde, Total Blocking Time de 0 ms et aucun décalage de mise en page. Sur ordinateur, c’est aussi 100, avec la plus grande image à 0,4 seconde.
Comment la porte décide
La porte crée un contexte WebGL jetable, lit le nom du moteur de rendu et y cherche SwiftShader, llvmpipe, softpipe et Basic Render. L’option failIfMajorPerformanceCaveat seule ne suffit pas : dans nos tests, Chrome headless sous SwiftShader fournit quand même un contexte.
Le chiffre qui nous a surpris
Sur un vrai GPU, la vérification prend 10 à 24 ms. Sous SwiftShader, créer ce premier contexte a pris 1,4 à 1,7 seconde du fil principal. La vérification coûte cher précisément là où la réponse est non. C’est pourquoi webgl-gate attend que la page soit chargée et que le navigateur soit libre avant de poser la question, et ne se trouve jamais sur le chemin critique.
L’utiliser
Installez-le avec npm et ne chargez votre scène que sur un vrai GPU. Sur le processeur, l’import n’est jamais appelé, donc le bundle n’est jamais téléchargé.
npm i webgl-gateimport { loadIfFastWebGL } from 'webgl-gate';
const scene = await loadIfFastWebGL(() => import('./scene'));
if (scene) scene.mount(canvas);Il existe aussi un hook React, useFastWebGL, et des recettes prêtes pour Next.js, three.js, React Three Fiber, Vue, Svelte et MapLibre. Le cœur pèse moins de 1 ko.
Ce qu’il ne fait pas
Il répond à une seule question : GPU ou pas. Pour savoir à quel point le GPU est puissant, detect-gpu de pmndrs classe les GPU selon des scores de benchmark. Le verdict n’est pas encore conservé d’une visite à l’autre : une réponse enregistrée pourrait survivre au matériel qu’elle décrit.