100 su PageSpeed con WebGL dal vivo, e il piccolo cancello dietro
Il sito del nostro studio mostra copertine di giochi animate, disegnate in WebGL, e ottiene comunque 100 in tutte e quattro le categorie di PageSpeed Insights, su smartphone e su computer. Una delle modifiche che ci hanno portato lì ora è un piccolissimo pacchetto open source: webgl-gate.
Lighthouse testa il mobile sulla CPU
PageSpeed Insights misura le pagine mobili con SwiftShader, un rasterizzatore che disegna WebGL con il processore invece che con la scheda grafica. Molte macchine virtuali, desktop remoti e browser con l’accelerazione hardware disattivata fanno lo stesso. Lì una scena WebGL non è solo lenta: già scaricare e analizzare il suo codice costa tempo al thread principale, e il Total Blocking Time lo mostra.
Il nostro sito ridisegnato partiva da 78 su mobile, e l’immagine più grande compariva dopo 4,2 secondi.
Cosa abbiamo cambiato
- CSS critico incorporato nell’HTML, così nulla blocca il primo disegno.
- WebGL solo dove una vera GPU disegna la pagina; altrove la pagina mostra immagini statiche e non scarica nemmeno PixiJS.
- Copertine AVIF responsive: gli smartphone ricevono immagini da 720 pixel, circa tre volte più leggere.
- Gli screenshot dei giochi aspettano che la copertina principale sia caricata.
Il mobile è salito a 100: immagine più grande a 1,7 secondi, Total Blocking Time di 0 ms e nessuno spostamento del layout. Su computer è sempre 100, con l’immagine più grande a 0,4 secondi.
Come decide il cancello
Il cancello crea un contesto WebGL usa e getta, legge il nome del renderer e cerca SwiftShader, llvmpipe, softpipe e Basic Render. L’opzione failIfMajorPerformanceCaveat da sola non basta: nei nostri test, Chrome headless con SwiftShader restituisce comunque un contesto.
Il numero che ci ha sorpreso
Su una vera GPU la verifica richiede 10–24 ms. Su SwiftShader, creare quel primo contesto ha richiesto 1,4–1,7 secondi di thread principale. La verifica costa proprio dove la risposta è no. Per questo webgl-gate aspetta che la pagina sia caricata e il browser sia libero prima di chiedere, e non sta mai nel percorso critico.
Come usarlo
Installalo con npm e carica la scena solo su una vera GPU. Sulla CPU l’import non viene mai chiamato, quindi il bundle non viene mai scaricato.
npm i webgl-gateimport { loadIfFastWebGL } from 'webgl-gate';
const scene = await loadIfFastWebGL(() => import('./scene'));
if (scene) scene.mount(canvas);C’è anche un hook per React, useFastWebGL, e ricette pronte per Next.js, three.js, React Three Fiber, Vue, Svelte e MapLibre. Il nucleo pesa meno di 1 kB.
Cosa non fa
Risponde a una sola domanda: GPU o no. Se ti serve sapere quanto è potente la GPU, detect-gpu di pmndrs classifica le GPU in base ai punteggi dei benchmark. Il verdetto non viene ancora salvato tra una visita e l’altra: una risposta salvata potrebbe sopravvivere all’hardware che descrive.