Урок 02

Core Web Vitals: LCP, INP, CLS

Что такое CWV

Core Web Vitals — метрики Google для оценки UX.

3 метрики:

  • LCP — Largest Contentful Paint.
  • INP — Interaction to Next Paint.
  • CLS — Cumulative Layout Shift.

Роль: сигнал ранжирования с 2021.

LCP

Что измеряет: время до отрисовки крупнейшего элемента в viewport.

Что считается:

  • Картинка — большая.
  • Видео.
  • Блок текста.
  • Background image.

Целевые значения:

  • < 2.5 сек — хорошо.
  • 2.5–4 сек — требует.
  • > 4 сек — плохо.

Что влияет на LCP

4 этапа:

  1. TTFB — ответ сервера.
  2. Resource load — загрузка.
  3. Resource load delay — ожидание.
  4. Element render delay — рендер.

Правило: чинить самый долгий этап.

Как улучшить LCP

TTFB:

  • Быстрый сервер.
  • Кеш (Redis, OPcache).
  • CDN.

Загрузка ресурсов:

  • Preload критичных.
  • fetchpriority="high" для LCP-картинки.
  • Формат WebP / AVIF.
  • Размер правильный.

Рендер:

  • Inline критический CSS.
  • Async некритичные скрипты.
  • font-display: swap.

Пример LCP-картинки

<img
    src="hero.webp"
    alt="Заголовок"
    width="1200"
    height="600"
    fetchpriority="high"
    decoding="async"
>

Что здесь:

  • fetchpriority="high" — приоритет.
  • width + height — против CLS.
  • decoding="async" — не блокирует.
  • WebP — современный формат.

⚠️ Не ставить loading="lazy" на LCP.

INP

Что измеряет: задержку между действием и отрисовкой.

Что заменяет: FID (First Input Delay) с 2024.

Целевые:

  • < 200 мс — хорошо.
  • 200–500 мс — требует.
  • > 500 мс — плохо.

Что влияет на INP

Long tasks:

  • JS дольше 50 мс.
  • Блокирует main thread.
  • Задержка отклика.

Что делать:

  • Разбить JS.
  • Web Workers.
  • Debounce обработчиков.
  • Меньше Client Components.

Как улучшить INP

1. Уменьшить JS:

  • Code splitting.
  • Tree shaking.
  • Lazy routes.
  • dynamic в Next.js.

2. Разбить длинные задачи:

async function process(items) {
    for (let i = 0; i < items.length; i++) {
        await new Promise((r) => setTimeout(r, 0));
        handle(items[i]);
    }
}

3. Debounce:

debounce(input.addEventListener('input', handler), 300);

4. Web Workers:

  • Тяжёлые вычисления вынести.

CLS

Что измеряет: сдвиги контента.

Что вызывает:

  • Картинки без размеров.
  • Реклама без места.
  • Шрифты без fallback.
  • Динамический контент.
  • Banners.

Целевые:

  • < 0.1 — хорошо.
  • 0.1–0.25 — требует.
  • > 0.25 — плохо.

Как улучшить CLS

1. Размеры картинок:

<img src="img.jpg" width="800" height="600" alt="">

2. aspect-ratio:

.card__image {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

3. Резерв под рекламу:

<div style="min-height: 250px;">
    <!-- реклама -->
</div>

4. Шрифты:

@font-face {
    font-family: 'Inter';
    src: url('inter.woff2') format('woff2');
    font-display: swap;
}

5. Не вставлять контент сверху:

  • Banners — не в потоке.
  • Cookie — overlay.
  • Modals — fixed.

Как измерять

Lab (Lighthouse):

  • Один прогон.
  • В идеальных условиях.
  • Для отладки.

Field (CrUX):

  • Реальные пользователи.
  • 28 дней.
  • Для решений.

Правило: смотреть оба — но решать по field.

PageSpeed Insights

Что показывает:

  • Field — реальные данные.
  • Lab — анализ.
  • Возможности оптимизации.
  • Диагностика.

URL: pagespeed.web.dev.

Web Vitals Extension

Что даёт:

  • Показывает метрики в реальном времени.
  • Зелёный / жёлтый / красный индикатор.

Установка: Chrome Web Store.

Chrome DevTools

Performance:

  • Запись сессии.
  • Long tasks видны.
  • Layout shifts показаны.

Lighthouse:

  • Полный аудит.
  • Рекомендации.

Влияние на SEO

Google:

  • CWV — сигнал ранжирования.
  • Mobile-first — метрики с мобильного.
  • AI Overviews — CWV важно.

Правило: плохие CWV → минус в выдаче.

Практика

1. Откройте PageSpeed Insights.

2. Запишите текущие CWV.

3. Прогоните Lighthouse в DevTools.

4. Найдите проблемы:

  • LCP > 2.5?
  • INP > 200?
  • CLS > 0.1?

5. Исправьте LCP: preload, fetchpriority.

6. Исправьте CLS: width, height, aspect-ratio.

7. Исправьте INP: меньше JS.

8. Замерьте снова.

Частые ошибки

1. Lazy на LCP:

LCP > 4 сек

Решение: fetchpriority="high".

2. Картинки без размеров:

CLS растёт

Решение: width + height.

3. Sync-скрипты в head:

Блокирует рендер

Решение: defer.

4. Много JS:

INP плохой

Решение: split.

5. Шрифты без swap:

FOIT

Решение: font-display: swap.

6. Banners без места:

CLS

Решение: min-height.

7. Lab вместо field:

Неверные выводы

Решение: оба.

8. Не проверять регулярно:

Деградация

Решение: мониторинг.

Итог

  • LCP < 2.5 сек.
  • INP < 200 мс.
  • CLS < 0.1.
  • LCP-картинка — fetchpriority="high".
  • width + height — против CLS.
  • font-display: swap.
  • Меньше JS — INP.
  • Code splitting.
  • Lab + Field.
  • Решать по field.

Дальше — Lighthouse и PageSpeed Insights.