Обсудить проект
Все статьи

Core Web Vitals на практике: как найти, что тормозит LCP, INP и CLS

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

Панель метрик: LCP 3,8 с — надо улучшить, INP 180 мс — хорошо, CLS 0,28 — плохо, с полосами заполнения

Плохая цифра в PageSpeed Insights — это симптом, а не диагноз. LCP складывается из четырёх частей, INP — из трёх фаз, CLS — из отдельных сдвигов, и у каждой части свои причины. Быстрее всего найти проблему, если разложить метрику на части и посмотреть, какая из них съедает время.

Статья для разработчиков и веб-мастеров. Ниже — как читать полевые и лабораторные данные, как разложить LCP, INP и CLS, таблица «симптом → причина → что сделать» и фрагменты кода.

Сначала: полевые данные или лаборатория

PageSpeed Insights показывает два вида данных (документация):

  • полевые — реальные пользователи Chrome за последние 28 дней, 75-й процентиль; появляются только при достаточном трафике;
  • лабораторные — один прогон Lighthouse на эмулированном устройстве; INP там не измеряется, вместо него показан Total Blocking Time.

Оценку Google делает по полевым данным. Лаборатория нужна, чтобы воспроизвести и отладить проблему. Если полевые данные хорошие, а лабораторные плохие, не спешите переписывать сайт: проверьте, похожи ли условия лаборатории на ваших реальных пользователей.

Пороги «хорошо» по web.dev: LCP до 2,5 с, INP до 200 мс, CLS до 0,1.

LCP: четыре части

LCP — время до отрисовки самого крупного элемента первого экрана. web.dev раскладывает его на четыре части и даёт ориентир по долям:

Таблица: Часть, Что это, Ориентир доли
ЧастьЧто этоОриентир доли
Time to First ByteОтвет сервера на запрос HTMLоколо 40%
Resource load delayПауза, прежде чем браузер начал грузить ресурс LCPменьше 10%
Resource load durationЗагрузка самого ресурса, например картинкиоколо 40%
Element render delayПауза между загрузкой ресурса и отрисовкойменьше 10%

Обе «задержки» должны стремиться к нулю. Если большая часть LCP приходится на них, проблема не в размере картинки, а в том, что браузер поздно о ней узнаёт или что-то мешает её отрисовать.

Полоса LCP, разделённая на четыре части по ориентиру web.dev: ответ сервера около 40%, пауза до загрузки менее 10%, загрузка ресурса около 40%, пауза до отрисовки менее 10%
Ориентир web.dev: доли частей LCP

Типичные причины и правки:

  • Картинка первого экрана подключена через CSS или JavaScript. Браузер находит её поздно. Ресурс LCP должен быть виден в HTML, иначе его стоит подгрузить заранее с высоким приоритетом.
  • Картинка первого экрана с lazy loading. web.dev прямо пишет: никогда не откладывайте загрузку LCP-изображения — это всегда добавляет задержку.
  • Синхронные скрипты в head. Они блокируют отрисовку; почти никогда не нужны.
  • Медленный ответ сервера. Кэширование страниц, CDN, отказ от лишних редиректов.
<img src="/images/hero.webp" width="1200" height="600"
     fetchpriority="high" alt="Описание первого экрана">

Высокий приоритет и никакого loading="lazy" — только для изображения первого экрана. Остальные картинки ниже по странице можно загружать отложенно.

INP: три фазы

INP — задержка между действием пользователя и следующей отрисовкой. web.dev делит взаимодействие на три фазы:

  • input delay — ожидание, пока основной поток освободится и начнёт обрабатывать событие;
  • processing duration — работа обработчиков события;
  • presentation delay — время до отрисовки следующего кадра.

Длинная первая фаза значит, что основной поток занят чем-то другим: скриптами аналитики, виджетами, инициализацией. Длинная вторая — что тяжёлый сам обработчик. Длинная третья — что после обработчика браузеру нужно перерисовать слишком много: большой DOM, массовые изменения разметки.

Три фазы INP от клика до следующего кадра: input delay — поток занят, processing — тяжёлый обработчик, presentation — много отрисовки
Фазы взаимодействия и типичная причина каждой

Главный приём — разбивать длинную работу и отдавать управление браузеру, чтобы он успел отрисовать ответ пользователю:

button.addEventListener('click', async () => {
  showSpinner();                          // сразу видимый ответ
  await new Promise(r => setTimeout(r));  // отдать поток на отрисовку
  heavyRecalculation();                   // тяжёлая часть — после
});

Найти медленные взаимодействия помогает панель Performance в Chrome DevTools: запишите профиль, повторите действие и посмотрите длинные задачи вокруг события. Начинать web.dev советует с полевых данных — они показывают, какие именно взаимодействия медленные у реальных людей.

CLS: откуда сдвиги

CLS суммирует неожиданные сдвиги макета. По web.dev, самые частые причины:

  • изображения и видео без размеров — браузер не резервирует место, пока не загрузит файл; решение — атрибуты width и height или CSS aspect-ratio;
  • веб-шрифты — подмена резервного шрифта на загруженный меняет размеры текста;
  • контент, вставленный сверху — баннеры, формы, уведомления; чем ближе к верху экрана, тем больше сдвиг; место под них нужно резервировать заранее.
.banner-slot { min-height: 120px; }      /* место под баннер */
.card-image  { aspect-ratio: 4 / 3; }    /* место под картинку */

Таблица: симптом → причина → что сделать

Таблица: Симптом, Вероятная причина, Что сделать
СимптомВероятная причинаЧто сделать
LCP плохой, большая задержка загрузки ресурсаКартинка в CSS или JS, lazy loading на первом экранеВынести в HTML, убрать lazy, поднять приоритет
LCP плохой, долгий ответ сервераНет кэша, тяжёлая генерация страницы, редиректыКэш страниц, CDN, прямые ссылки без редиректов
LCP плохой, долгая загрузка картинкиТяжёлый файл, неподходящий форматСжатие, современный формат, размеры под экран
INP плохой, большая задержка вводаОсновной поток занят сторонними скриптамиОтложить или убрать лишние скрипты
INP плохой, долгая обработкаТяжёлый обработчик событияРазбить работу, отдать поток на отрисовку
INP плохой, долгая отрисовкаБольшой DOM, массовые изменения разметкиУменьшить DOM, обновлять только нужное
CLS плохой при загрузкеКартинки без размеров, шрифтыwidth и height, aspect-ratio
CLS плохой при прокрутке или после загрузкиБаннеры и виджеты, вставленные сверхуРезервировать место, показывать ниже

Порядок работы

  1. Посмотрите полевые данные: какая метрика плохая и на каких типах страниц.
  2. Воспроизведите проблему в лаборатории и в DevTools на медленном профиле.
  3. Разложите метрику на части и найдите самую большую.
  4. Исправьте одну причину и проверьте результат в лаборатории.
  5. Дождитесь обновления полевых данных — они собираются за 28 дней.

В разработке сайтов PIP перед запуском проверяются страницы, формы и мобильная версия — см. страницу разработки сайтов. Сайт медленный и непонятно почему? Расскажите о задаче — разберём метрики по частям.

Короткие подсказки о сайтах и автоматизации — в Telegram-канале @pip_kz.

Ещё по этой теме

Изображения на сайте: WebP, AVIF, srcset и lazy loading

Как готовить изображения для сайта: какие форматы для чего, picture с запасным вариантом, srcset и sizes, размеры против сдвигов макета, отложенная загрузка ниже первого экрана и приоритет для LCP-картинки, имена файлов и alt — с примерами разметки и чек-листом.

Хостинг для сайта: на что смотреть, кроме цены

Как выбрать хостинг: девять критериев с вопросами к провайдеру, типы хостинга, вопрос о месте хранения персональных данных в Казахстане, правило «аккаунт на компании» и порядок смены хостинга.

Доступность сайта: базовые проверки за час

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

Обсудим вашу задачу

Разберёмся в деталях и предложим план.

Обсудить проект

Просмотр изображения