Проблема начинается с отчёта «страница медленная». Цена такого диагноза — оптимизировать не тот участок: уменьшить JavaScript, пока главный баннер ждёт шрифт, или ускорить первый paint, оставив клик заблокированным длинной задачей. Одно среднее число скрывает разные виды задержки.
Причина — смешать LCP, INP и CLS в общий score без определения окна и percentile. LCP отвечает за крупнейший видимый элемент, INP — за отзывчивость взаимодействий, CLS — за неожиданные сдвиги. У каждой метрики свой источник, порог и способ исправления. Сначала нужно понять измерение, затем выбирать действие.
Три метрики — три пользовательских вопроса
LCP показывает, когда крупнейший контентный элемент стал видимым в пределах загрузки. Большой LCP часто связан с TTFB, критическим CSS, размером изображения или шрифтом. INP оценивает задержку взаимодействий и указывает на работу main thread после ввода. CLS суммирует неожиданные сдвиги layout, например из-за изображения без размеров или поздней рекламы.
Метрика не говорит, где находится причина. Плохой LCP может быть следствием сервера, сети или браузера; плохой INP — длинной задачи, стороннего скрипта или тяжёлого обработчика; плохой CLS — отсутствующего места под контент. Поэтому budget должен включать и измерение, и диагностический разрез: URL, устройство, connection, release и элемент.
| Метрика | Вопрос пользователя | Хорошая граница | Первый разрез |
|---|---|---|---|
| LCP | крупнейший контент появился? | ≤ 2500 ms | TTFB, resource, element |
| INP | интерфейс ответил после ввода? | ≤ 200 ms | long task, handler, device |
| CLS | страница не сдвинулась? | ≤ 0.1 | element, font, reserved space |
| Percentile | у какой доли пользователей проблема? | p75 по сегменту | country, device, release |
| Budget | какой порог блокирует выпуск? | явно в CI/monitoring | threshold + owner action |
Budget не равен среднему
Среднее значение сглаживает хвост и может выглядеть здоровым при плохом опыте части пользователей. Для пользовательских web-метрик часто нужен p75 в определённом сегменте, но даже percentile не спасает от смешения мобильных и десктопных данных. Порог должен быть привязан к одинаковому URL, устройству, версии и периоду наблюдения.
Лабораторный Lighthouse и field data отвечают на разные вопросы. Лаборатория воспроизводима и удобна для CI, но не содержит реального разнообразия сети. Field data показывает пользователей, но зависит от sampling, трафика и состава сегмента. Решение об оптимизации подтверждайте обоими видами данных или честно называйте, какой слой измерен.
Runnable-пример: классифицировать три числа
Функция принимает миллисекунды LCP и INP, а также значение CLS. Она возвращает статус каждой метрики и общий худший статус. Это учебный классификатор, не реализация браузерного PerformanceObserver: реальные значения нужно собирать из API и агрегировать по сегментам. Входы ниже показывают пороги без округления.
import { classifyWebVitals } from './upgrade-2027-12.mjs';
const release = classifyWebVitals({
lcpMs: 2180,
inpMs: 240,
cls: 0.08,
});
const invalid = classifyWebVitals({
lcpMs: 1200,
inpMs: -1,
cls: 0.02,
});
console.log(release.overall, release.lcp, release.inp, release.layout);
console.log(invalid.ok, invalid.reason);
// needs-improvement good needs-improvement good
// false vital-input-invalidПорядок поиска причины
- Определите URL, сегмент, percentile и окно измерения. Не сравнивайте p75 мобильного трафика со средним для всех устройств.
- Для плохого LCP найдите element и разделите TTFB, загрузку ресурса и отрисовку. Для INP найдите interaction и long task; для CLS — shifted element.
- Сформулируйте один budget на релиз и один diagnostic signal. Не блокируйте сборку по метрике, которую CI не может воспроизвести.
- Проверьте lab fixture и field distribution отдельно. Разница между ними — информация о среде, а не повод выбрать удобный источник.
- Измените один тяжёлый участок: critical resource, handler, image dimensions или layout reservation.
- Повторите измерение тем же сегментом и окном. Снижение LCP не закрывает INP/CLS автоматически.
Почему порог не является причинностью
Пересечение границы 2500 мс сообщает о классификации, но не объясняет, что исправить. Порог полезен для triage и разговора о риске, а не для выбора виновника. Если после preload LCP улучшился, это ещё не доказывает, что preload был единственной причиной: изменились сервер, кэш или состав трафика.
У performance есть побочный эффект оптимизации. Сжатие изображения уменьшает LCP, но может увеличить CPU-декодирование или ухудшить качество. Разделение JavaScript может помочь INP, но добавить запросы и повлиять на LCP. В budget следует держать соседние ограничения — error rate, size, long tasks — и проверять, что выигрыш одной метрики не создаёт новый долг.
Ограничения и следующий шаг
Классификатор использует учебные пороги и не считает реальные percentile. W3C LCP и Performance Timeline описывают API и объект измерения, но не обещают, что конкретный dashboard правильно собрал данные. INP и CLS требуют своих источников и сегментации; один локальный запуск не является field evidence.
Следующий шаг — выбрать один URL и сделать таблицу p75 для LCP, INP и CLS по двум сегментам. Для каждой плохой строки добавьте element/interaction и один проверяемый сигнал причины. После оптимизации повторите ту же выборку и проверьте соседние метрики, а не только тот показатель, который был в заголовке задачи.
Проверяемые источники
- W3C Largest Contentful Paint — W3C Web Performance Working Group, Working Draft, страница проверена 31 июля 2026 года. Применение: Определяет Largest Contentful Paint и API наблюдения за крупнейшей отрисовкой, чтобы измерение имело точный объект. Граница: Working Draft может изменяться; LCP не измеряет всю скорость страницы, отзывчивость или стабильность layout.
- W3C Performance Timeline — W3C Candidate Recommendation Draft, 21 мая 2025 года. Применение: Задаёт Performance Timeline и доступ к измеряемым entry, на которых строятся браузерные наблюдения. Граница: Не задаёт ваши пороги, backend-агрегацию, sampling и причинность медленной страницы.
- Web Vitals — web.dev — Google web.dev, опубликовано 4 мая 2020 года, обновлено 31 октября 2024 года. Применение: Фиксирует рекомендованные пороги LCP, INP и CLS и правило p75 по сегментам для практического triage. Граница: Это guidance, а не гарантия UX и не доказательство причины конкретной регрессии.