100 у PageSpeed із живим WebGL і маленькі ворота, що це дають
Сайт нашої студії показує живі обкладинки ігор, намальовані через WebGL, і все одно отримує 100 в усіх чотирьох категоріях PageSpeed Insights — і на телефоні, і на комп’ютері. Одна зі змін, що нас туди привела, тепер — крихітний відкритий пакет: webgl-gate.
Lighthouse міряє мобільну версію на процесорі
PageSpeed Insights вимірює мобільні сторінки на SwiftShader — растеризаторі, який малює WebGL процесором, а не відеокартою. Так само працюють багато віртуальних машин, віддалених робочих столів і браузерів із вимкненим апаратним прискоренням. Там WebGL-сцена не просто гальмує: саме завантаження й розбір її коду забирають час головного потоку, і це видно в Total Blocking Time.
Наш оновлений сайт стартував із 78 балів на телефоні, а найбільше зображення з’являлося через 4,2 секунди.
Що ми змінили
- Критичний CSS вбудовано в HTML — ніщо не блокує перше малювання.
- WebGL — лише там, де сторінку малює справжня відеокарта; деінде показуємо статичну картинку й навіть не завантажуємо PixiJS.
- Адаптивні обкладинки AVIF: телефони отримують зображення на 720 пікселів, приблизно втричі легші.
- Скріншоти ігор чекають, поки завантажиться головна обкладинка.
Мобільна оцінка піднялася до 100: найбільше зображення — за 1,7 секунди, Total Blocking Time — 0 мс, зсувів макета немає. На комп’ютері — теж 100, найбільше зображення за 0,4 секунди.
Як ворота вирішують
Ворота створюють одноразовий контекст WebGL, читають назву рендерера і шукають у ній SwiftShader, llvmpipe, softpipe і Basic Render. Самого прапорця failIfMajorPerformanceCaveat недостатньо: у наших тестах headless Chrome на SwiftShader усе одно видає контекст із ним.
Число, яке нас здивувало
На справжній відеокарті перевірка займає 10–24 мс. На SwiftShader створення першого контексту забрало 1,4–1,7 секунди головного потоку. Перевірка дорога саме там, де відповідь — «ні». Тому webgl-gate чекає, поки сторінка завантажиться і браузер звільниться, і ніколи не стоїть на критичному шляху.
Як користуватися
Встановіть пакет через npm і завантажуйте сцену лише на справжній відеокарті. На процесорі імпорт не викликається взагалі, тож бандл навіть не завантажується.
npm i webgl-gateimport { loadIfFastWebGL } from 'webgl-gate';
const scene = await loadIfFastWebGL(() => import('./scene'));
if (scene) scene.mount(canvas);Є й хук для React — useFastWebGL — та готові рецепти для Next.js, three.js, React Three Fiber, Vue, Svelte і MapLibre. Ядро важить менше кілобайта.
Чого він не робить
Пакет відповідає на одне питання: відеокарта чи ні. Якщо треба знати, наскільки вона потужна, detect-gpu від pmndrs класифікує відеокарти за результатами бенчмарків. Вердикт поки не кешується між візитами: збережена відповідь може пережити залізо, яке описує.