Перфоманс-бюджет — это договор команды о том, какую скорость мы считаем приемлемой и как защищаем её от деградации. В Schedars мы держим Lighthouse 95+ на сайтах клиентов не магией, а системой ограничений и проверок. Этот пост — про то, как именно.
Контекст
Core Web Vitals давно стали фактором ранжирования и фактором конверсии. LCP меньше 2.5 секунд, CLS меньше 0.1, INP меньше 200 миллисекунд — это не academic targets, это пороги, ниже которых пользовательский опыт начинает проседать заметно. Проблема в том, что без бюджета производительность ухудшается с каждым релизом: добавили шрифт, подключили скрипт, вставили видео — и через полгода LCP уже 4 секунды.
Подход
Мы фиксируем бюджет в начале проекта и проверяем его на каждом PR. Бюджет — это не только Lighthouse score, это конкретные числа: размер JS bundle, количество шрифтов, размер LCP-изображения, число third-party скриптов. Если PR превышает бюджет, он не вливается без обсуждения. Astro как базовый стек помогает: zero JS by default, partial hydration, build-time оптимизация изображений.
Что мы делаем
- JS bundle budget: верхний предел в килобайтах per route, проверка в CI
- Изображения: только Astro Image, AVIF/WebP, корректный sizes и srcset
- Шрифты: subset под латиницу/кириллицу, font-display: swap, preload только для LCP-шрифта
- Third-party: жёсткий аудит, асинхронная загрузка, лимит по числу
- CLS: явные размеры для всех медиа, резерв места под динамический контент
- INP: вынос тяжёлых вычислений в idle callback или web worker
Чему научились
Перфоманс-бюджет работает только если он автоматизирован. Договорённости в Notion забываются через месяц; CI-проверка — нет. Мы используем Lighthouse CI и size-limit в pipeline, и любое превышение порога — это явный red в проверке PR. Второй урок — INP важнее, чем кажется: пользователь не замечает 200 миллисекунд, но замечает 500 миллисекунд, особенно на средних телефонах. Поэтому тестируем не на MacBook Pro, а на mid-tier Android.
Что дальше
Хотите аудит производительности или новый проект с бюджетом, заложенным с первого дня? Напишите через /contacts — покажем конкретные точки роста.