Новое в журнале. Маленькие pull request: почему их быстрее ревьюят и как резать задачу
Практика и проекты

Бюджет производительности сайта: как задать, измерить и удержать в CI

Разбираем Core Web Vitals (LCP, INP, CLS) и показываем, как превратить ощущение «сайт тормозит» в числовой бюджет, который проверяется автоматически в пайплайне.

17 марта 20269 мин чтенияПрактикам
Бюджет производительности сайта: как задать, измерить и удержать в CI
2.5 спорог LCP «хорошо»
200 мспорог INP «хорошо»

«Сайт стал тормозить», фраза, с которой обычно начинается разговор о производительности, и обычно заканчивается она либо героическим рефакторингом под дедлайн, либо списком «потом поправим». Бюджет производительности переворачивает порядок: вместо того чтобы разбираться с проблемой постфактум, команда заранее фиксирует числовые пределы для ключевых метрик и не пускает в продакшен изменения, которые эти пределы нарушают. Это такой же инженерный контракт, как лимит на размер бинарника или максимальное число запросов к базе на один HTTP-запрос.

Core Web Vitals в 2026 году

Google использует три основные метрики как сигнал ранжирования и как ориентир для индустрии. LCP, Largest Contentful Paint, измеряет, когда на экране отрисовался самый крупный видимый блок контента, порог «хорошо», до 2.5 секунды. INP, Interaction to Next Paint, заменил устаревший FID и измеряет задержку отклика интерфейса на любое взаимодействие пользователя за всё время сессии, а не только на первое; порог «хорошо», до 200 миллисекунд. CLS, Cumulative Layout Shift, считает суммарный сдвиг вёрстки от неожиданного смещения блоков, порог «хорошо», до 0.1. Важно: эти три метрики измеряют разные стадии жизни страницы, загрузку, взаимодействие и визуальную стабильность, и бюджет должен охватывать все три отдельно, а не сводиться к одному общему баллу.

МетрикаЧто измеряетПорог «хорошо»
LCPВремя отрисовки крупнейшего контентного блокаДо 2.5 с
INPЗадержка отклика на взаимодействиеДо 200 мс
CLSСуммарный сдвиг макетаДо 0.1
Главная мысльБюджет без принудительной проверки в CI, это пожелание, которое команда забудет проверить перед релизом уже через месяц

Как перевести «медленно» в цифры бюджета

Бюджет имеет смысл только если он связан с конкретными страницами и конкретными сценариями, а не с абстрактным «сайт в целом». Разумная практика: выделить 3-5 ключевых страниц, главную, карточку товара или статью, страницу оформления заказа, и задать для каждой свой набор порогов, потому что у них разная структура контента и разная терпимость пользователя к задержке. Помимо трёх метрик Core Web Vitals стоит добавить технические бюджеты, которые на них напрямую влияют: суммарный вес JavaScript на странице, число сторонних скриптов, число запросов к шрифтам. Эти вторичные бюджеты проще контролировать на этапе код-ревью, потому что они не требуют реального браузера для измерения.

  • Бюджет JS на странице: например, не более 250 КБ сжатого кода на первый экран
  • Число сторонних доменов, аналитика, виджеты, реклама: фиксированный потолок, каждое превышение требует согласования
  • Число веб-шрифтов и их форматов: предпочитать woff2 и ограниченный набор начертаний

Измерение: лабораторные данные и данные реальных пользователей

Лабораторные измерения запускаются в контролируемой среде с фиксированной сетью и устройством, они воспроизводимы и удобны для CI, но не показывают, что видят реальные пользователи на старых телефонах и нестабильном мобильном интернете. Данные реальных пользователей, RUM, собираются через API браузера и агрегируются по перцентилям, обычно смотрят на 75-й процентиль, а не на среднее значение, потому что среднее скрывает худшие случаи. Правильная практика, держать оба источника: лабораторные тесты в CI ловят регрессию до релиза, RUM показывает, что реально происходит у аудитории, и ловит проблемы, которые воспроизводятся только на конкретных устройствах или в конкретных регионах.

if ('PerformanceObserver' in window) {
  new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      sendToAnalytics(entry.name, entry.startTime, entry.duration);
    }
  }).observe({ type: 'largest-contentful-paint', buffered: true });
}
Вы в начале разбораДальше: разбор компромиссов, чек-лист и ответы на частые вопросы.

Бюджет в CI: как не дать регрессии доехать до продакшена

Самый надёжный способ удержать бюджет, не полагаться на память команды, а встроить проверку в пайплайн. Инструменты для автоматического аудита позволяют задать пороги прямо в конфигурации и завалить сборку, если метрика страницы превысила лимит. Технически это выглядит так: после деплоя на превью-окружение пайплайн запускает аудит для списка URL, сравнивает результат с заданными порогами и возвращает ненулевой код выхода при провале, что останавливает merge. Важная деталь: лабораторные измерения в CI шумные, виртуальные машины делят ресурсы с другими задачами, поэтому порог стоит задавать не на одно измерение, а на медиану из 3-5 прогонов, и давать небольшой запас, чтобы не ловить ложные провалы из-за шума окружения.

Бюджет без принудительной проверки в CI, это пожелание, а не контракт. Через месяц любой ручной процесс забудут проверить перед релизом.

Частые ошибки при внедрении бюджета

Как подать бюджет команде, чтобы его не саботировали

Технически настроенный бюджет в CI не гарантирует, что команда его примет: если порог проваливается на каждом втором merge request, разработчики быстро найдут способ отключить проверку или начнут игнорировать её статус. Поэтому внедрение стоит начинать не с жёсткого блокирующего порога, а с режима предупреждения: несколько недель бюджет только пишет комментарий в pull request с текущими цифрами, без остановки сборки, и команда привыкает видеть эти числа рядом с обычным код-ревью. Только после того как большинство изменений укладывается в целевые пороги естественным образом, проверку переводят в блокирующий режим.

Важно также договориться заранее о процессе исключений: иногда конкретная фича объективно требует временного превышения бюджета, например, интеграция нового виджета поддержки по требованию бизнеса. Должен существовать понятный путь согласованного исключения (явный комментарий в конфигурации с ссылкой на задачу и сроком пересмотра), а не обходной путь через полное отключение проверки для всего репозитория. Без такого процесса команда либо саботирует бюджет при первом конфликте интересов, либо жёсткий порог тормозит легитimные релизы и настраивает разработчиков против самой идеи бюджета.

Помимо порогов на сами метрики, полезно договориться о формате отчёта, который видит команда при каждом провале проверки. Голый код возврата без деталей заставляет разработчика заново запускать профилирование локально, чтобы понять причину. Удобнее, когда пайплайн сразу прикладывает ссылку на детальный отчёт с разбивкой по стадиям загрузки страницы, списком самых тяжёлых ресурсов и диффом по сравнению с предыдущим успешным прогоном. Такой отчёт превращает проверку бюджета из формального препятствия в инструмент, который сразу показывает, что чинить, и команда тратит на устранение регрессии минуты, а не часы на повторную диагностику с нуля.

Полезно также пересматривать сами пороги бюджета не реже раза в полгода, потому что типичные устройства и сети аудитории меняются, а конкуренты в нише могут подтянуть свою производительность. Бюджет, зафиксированный один раз и забытый, рискует через пару лет превратиться либо в слишком мягкое ограничение, которое не защищает от реальных проблем, либо в устаревший стандарт, который не отражает актуальные ожидания пользователей.

Короткое практическое правило для новых проектов: закладывайте бюджет производительности в техническое задание рядом с функциональными требованиями с самого первого спринта, а не после того как страница уже обросла виджетами и сторонними скриптами, которые потом болезненно урезать.

  • Один общий бюджет на все страницы сайта вместо отдельных порогов под разные типы страниц
  • Проверка только на десктопе, хотя большая часть трафика у многих продуктов идёт с мобильных устройств на слабых сетях
  • Бюджет заводят, но не привязывают к CI, и он превращается в документ, который никто не открывает после первой недели
  • Игнорирование сторонних скриптов, виджетов поддержки, трекеров, при расчёте бюджета, хотя часто именно они основной источник деградации

Частые вопросы

С чего начать внедрение бюджета производительности в существующем проекте?

Сначала измерьте текущее состояние ключевых страниц лабораторно и через RUM, зафиксируйте эти числа как исходную точку, и только потом ставьте целевой бюджет чуть лучше текущего состояния. Бюджет, который сразу требует двукратного улучшения, саботируют уже на первой неделе.

INP заменил FID полностью, нужно ли вообще отслеживать старую метрику?

Google официально вывел FID из набора Core Web Vitals в пользу INP ещё в 2024 году, поэтому отдельно отслеживать FID в 2026 году не нужно, достаточно INP, который даёт более полную картину отклика интерфейса за всю сессию.

Нужно ли одинаковый бюджет для десктопа и мобильных устройств?

Нет, разумнее задавать отдельные пороги: мобильные сети и процессоры медленнее, и требование десктопных цифр от мобильной версии приведёт либо к постоянным провалам CI, либо к искусственному ослаблению бюджета до бесполезного уровня.

Код, который не стыдно передать

Начните с принципов, а дальше двигайтесь по рубрикам. Каждый разбор заканчивается чек-листом.

Случайный разбор