Оптимизация LCP, CLS, INP: принципы, паттерны и чек-листы

Core Web Vitals — это не «оценка Google», а набор метрик про реальный опыт: как быстро появляется крупный контент (LCP), насколько «прыгает» верстка (CLS) и как отзывчиво ведут себя интерфейсы (INP). В этом материале — практики, которые мы применяем при разработке сайта под ключ и при редизайне существующих продуктов: стратегии рендеринга, загрузка шрифтов/медиа, управление состояниями компонентов UI, контроль аналитики и чек-листы. Сроки/стоимость разработки уточняйте по контактам на сайте.

1) LCP (Largest Contentful Paint): как показать главное раньше

LCP — крупный элемент выше фолда: фото героя, заголовок, фон-блок с изображением. Цель: уложиться до 2.5 с на мобильных. На практике LCP гасит не «медленный сервер», а цепочка мелочей: неоптимальные шрифты, ленивые критичные изображения, блокирующие скрипты, долгое разрастание CSS.

Паттерны ускорения LCP

  • Сервер и кэш. SSR/SSG для первого экрана, HTTP/2+, короткий TTFB, кэш на краю. Для динамики — стабильные API-времена, статика через CDN.
  • Изображения героя. Используйте оптимизатор картинок, корректный размер контейнера, форматы WebP/AVIF, атрибутыwidth/height и без lazy-load для LCP-изображения.
  • Шрифты. Предзагрузка заголовочного шрифта, font-display: swap или optional, system fallback, подмножества (subset) и вар-шрифты при необходимости.
  • CSS-критика. Минимизируйте критический CSS, не тяните крупные UI-библиотеки для первого экрана. Утяжеляющие стили — по требованию.
  • JS-режим экономии. Компоненты ниже фолда — динамическим импортом; аналитика и виджеты — с отложенным стартом.
  • Приоритеты сети. preload LCP-изображения,preconnect к доменам медиа и шрифтов; не злоупотребляйте лишними preconnect — это тоже запросы.

Отдельный выигрыш — «содержательный» заголовок как LCP. Если визуально первый смысл — крупный H1, сделайте его LCP: текст приходит вместе с HTML и показывает ценность сразу, пока изображение догружается.

2) CLS (Cumulative Layout Shift): как зафиксировать верстку

CLS — сумма непредвиденных сдвигов во время загрузки. Причины: медиа без размеров, веб-шрифты, баннеры/виджеты, вставки над контентом, динамическая высота блоков. Цель — < 0.1.

Паттерны фиксации CLS

  • Резерв под медиа. Всегда задавайте width/height или соотношение сторон (aspect-ratio) для изображений, видео, iframes.
  • Шрифты. Используйте font-display: swap и сопоставимые fallback шрифты (метрики близкие к основному), чтобы замена не «прыгала».
  • Реклама/виджеты. Резервируйте место, не вставляйте «вверх» над уже отрисованным текстом; добавляйте placeholder с фиксированной высотой.
  • Хедер/баннеры. Высота известна заранее; sticky-панели не должны появляться внезапно. Если вводите cookie-бар — не сдвигайте контент.
  • Поздние вставки. Обновляйте контент внутри зарезервированных контейнеров, а не вставляйте новые блоки над текстом.

3) INP (Interaction to Next Paint): отзывчивость действий

INP измеряет «самое медленное» пользовательское действие: клик, тач, клавиатура. Цель — < 200–250 мс для основной массы пользователей. Главные враги: тяжёлые обработчики, блокирующий main-thread, моментальная «гидратация всего» и громоздкие эффектные анимации.

Паттерны снижения INP

  • Разделяйте работу. Крупные вычисления — в web worker; при клике сначала меняйте UI (оптимистичные состояния), тяжёлое — после.
  • Дебаунсы и батчинг. Для ввода и resize — дебаунс; для сетевых кликов — батчинг запросов.
  • Lazy-гидратация. Не гидратируйте весь экран сразу. Компоненты ниже фолда — по пересечению с viewport; вторичные виджеты — по взаимодействию.
  • Мелкий JS. Избегайте больших зависимостей, следите за bundle-splitting, используйте ESM и tree-shaking.
  • Анимации без «стоп-кадра». Анимируйте transform/opacity, избегайте layout-триггеров (width/height/top/left), поддерживайте will-change точечно.

4) Состояния компонентов UI: видимая работа интерфейса

Состояния компонентов UI — основной инструмент контроля перцептивной скорости. Пользователь должен видеть, что происходит: загрузка, успех, ошибка, пусто, ожидание подтверждения. Если UI молчит, клики накапливаются и INP растёт.

Необходимый набор состояний

  • Loading: скелетоны и предзаголовки вместо «пустых полотен».
  • Disabled: кнопка блокируется на время запроса; спиннер — внутри кнопки.
  • Optimistic: мгновенно меняем UI (лайк, добавление в корзину) и догоняем сетью.
  • Empty: контент «что дальше» вместо тишины.
  • Error: человеческий текст ошибки, повторить, канал связи.
  • Focus-visible: контрастные фокусы для клавиатуры и мыши.

Главное — предсказуемость. Кнопка «Оплатить» не может «оживать» спустя секунду без обратной связи. Даже короткая блокировка с индикатором даёт ощущение контроля и снижает «дребезг» кликов.

5) Архитектура загрузки: что, где и когда рендерить

Производительность — это стратегия рендеринга. Условно: сервер рендерит смысл, клиент оживляет детали. Критичное — на сервере, вторичное — позднее или по событию.

  • Критический путь. Текст первого экрана рендерится вместе с HTML, LCP-блок виден сразу, без JS.
  • Композиция модулей. Виджеты, слайдеры, карты, чаты — по lazy-паттерну.
  • Данные по требованию. «Сверху вниз» — минимум запроса; развороты деталей — по клику.
  • Кэш и валидность. Stale-while-revalidate для «почти статических» данных; ручное инвалидационное событие для чувствительных секций.

6) Шрифты и типографика: красиво без «прыжков»

Шрифты — частая причина и LCP-замедлений, и CLS. Базовые правила: один-два семейства, веса по делу, предзагрузка заголовочного, близкий по метрикам fallback (например, для русскоязычных — system UI).

  • font-display: swap или optional, чтобы текст был сразу.
  • Subsetting: вынесите кириллицу и латиницу при необходимости.
  • Variable fonts: один файл вместо пяти — меньше запросов, выше контроль веса.
  • Предзагрузка: только критичных начертаний, не всего семейства.

7) Изображения и видео: вес, размер, первичность

Медиа — самый тяжёлый актив. LCP-изображение — без lazy, остальное — после. Video-постеры с правильным размером; автоплей — только без звука и если не мешает чтению.

  • Используйте современные форматы (WebP/AVIF) и правильные размеры контейнеров.
  • Для галерей/каруселей — lazy + content-visibility за пределами viewport.
  • Серверные трансформации изображений для разных DPR и брейкпоинтов.
  • Плейсхолдеры (blur) — для перцептивной скорости, но не вместо оптимизации.

8) JS-бюджет: сколько кода «можно» на первый экран

Бюджет — это договорённость, а не догма. Часто достаточно 60–100 КБ сжатого JS на первый экран. Важнее дисциплина: каждый импорт — взвешенно, каждый «удобный хелпер» — через линзы бандла.

  • ESM и tree-shaking, без «общих» файлов с побочками.
  • Разделение маршрутов: код страницы не должен тянуть код соседних страниц.
  • Тяжёлые зависимости — по динамическому импорту «только когда нужно».
  • Слежение за регрессом: отчёты бандла и лимиты в CI.

9) Аналитика и измерения: что считаем «зелёной зоной»

Лабораторные замеры полезны, но правит бал полевой трафик (RUM). Отслеживайте LCP/CLS/INP для реальных пользователей с разбивкой по устройствам, странам и шаблонам страниц. В метриках важен не «средний», а перцентиль P75.

  • События рендеринга и ошибок фронта в едином хранилище с дашбордом.
  • Разделение по шаблонам: главная, список, карточка, форма, чек-аут.
  • Алерты на деградацию: падение в зелёную зону, внезапный рост CLS по типу страницы.
  • Корреляция: где INP «стреляет» после релиза — смотрим новые обработчики и анимации.

10) Чек-листы перед релизом

LCP

  • Критический текст в SSR, LCP-изображение без lazy, с preload и размером.
  • Шрифты предзагружены выборочно, есть fallback, font-display настроен.
  • Критический CSS минимален, виджеты/аналитика — отложены.

CLS

  • Все медиа с width/height или aspect-ratio, sticky — с заранее заданной высотой.
  • Cookie/уведомления не сдвигают контент; шрифты не вызывают «скачки».
  • Поздние вставки не ломают поток, место зарезервировано.

INP

  • Нет тяжёлых синхронных обработчиков; интеракции сначала обновляют UI.
  • Lazy-гидратация вне экрана; формам добавлены оптимистичные состояния.
  • Анимации — на transform/opacity, без layout-триггеров.

11) Анти-паттерны

  • Lazy-load LCP-изображения «на всякий случай».
  • Длинные CSS-анимации ширины/высоты на первом экране.
  • Скрытая блокирующая аналитика и виджеты в head.
  • Глобальные CSS, которые тянут стили всех компонентов на любую страницу.
  • Отсутствие состояний компонентов UI — пользователь «долбится» в неотвечающий интерфейс.

Итог простой: оптимизация LCP, CLS, INP — это не «магия» и не разовая настройка, а архитектурная дисциплина. Чем раньше вы закладываете стратегии рендеринга, загрузки шрифтов/медиа и состояния компонентов, тем стабильнее растёт продукт: страницы быстрее, интерфейсы предсказуемее, а метрики — в зелёной зоне. Сроки/стоимость разработки уточняйте по контактам на сайте.

let's discuss your project

Your company is ready for big changes and we will help with that

Or write to us on
01
02
03
04
Image or document up to 15 MB
05
06