Коротко. Core Web Vitals — три метрики реального опыта посетителя: LCP (скорость отрисовки главного элемента, хорошо — до 2,5 с), INP (отзывчивость на клики и тапы, до 200 мс) и CLS (визуальная стабильность, до 0,1). Оценка берётся на 75-м перцентиле реальных визитов за скользящее окно, а не по одному прогону Lighthouse. Состав метрик и пороги Google периодически пересматривает.
Что такое Core Web Vitals и зачем они нужны
Core Web Vitals (CWV) — подмножество метрик инициативы Web Vitals от Google. Из десятков технических показателей производительности выбраны три, которые ближе всего к субъективному ощущению «сайт быстрый»: успел ли появиться контент, отвечает ли страница на нажатия, не прыгает ли вёрстка под пальцем.
Принципиальная разница с привычными метриками вроде TTFB, DOMContentLoaded или «веса страницы» — в точке измерения. TTFB описывает работу инфраструктуры, CWV описывают восприятие. Страница может весить 4 МБ и ощущаться быстрой, если первый экран отрисовался за секунду, а остальное догрузилось позже. И наоборот: лёгкая страница с блокирующим шрифтом и рекламой, которая вставляется над текстом, ощущается сломанной при любом весе.
Второе отличие — метрики собираются в браузере посетителя, а не на стенде. Итоговая оценка страницы берётся на 75-м перцентиле распределения: «хорошо» означает, что как минимум трём четвертям визитов было хорошо. Один медленный визит из метро картину не портит, а систематическая просадка на бюджетных Android-устройствах — портит, даже если на вашем ноутбуке всё зелёное.
Третье: метрики считаются отдельно для мобильных и десктопных визитов. Типовая ситуация — десктоп зелёный, мобильные красные, потому что мобильный процессор в несколько раз слабее и весь JavaScript выполняется дольше.
Хорошие Core Web Vitals — не самоцель ради SEO. Это прокси-показатель удовлетворённости: быстрый, отзывчивый и стабильный интерфейс лучше удерживает и лучше конвертирует. Ранжирование здесь — побочный эффект, а не главный приз.
Три метрики и их пороги
У каждой метрики три зоны: «хорошо», «требует улучшения», «плохо». Страница считается прошедшей проверку, только если все три метрики попали в зелёную зону на 75-м перцентиле.
| Метрика | Что измеряет | Хорошо | Требует улучшения | Плохо |
|---|---|---|---|---|
| LCP Largest Contentful Paint | Время до отрисовки самого крупного видимого элемента первого экрана | ≤ 2,5 с | 2,5–4,0 с | > 4,0 с |
| INP Interaction to Next Paint | Задержка между действием пользователя и следующей отрисовкой кадра | ≤ 200 мс | 200–500 мс | > 500 мс |
| CLS Cumulative Layout Shift | Суммарный неожиданный сдвиг макета (безразмерная величина) | ≤ 0,1 | 0,1–0,25 | > 0,25 |
Полезно понимать, на что каждая метрика реагирует, — тогда становится ясно, кто в команде за неё отвечает.
| Что вы меняете | LCP | INP | CLS |
|---|---|---|---|
| Скорость ответа сервера, кеш, CDN | Сильно | Слабо | Нет |
| Вес и формат изображений первого экрана | Сильно | Нет | Косвенно |
| Объём и разбиение JavaScript | Средне | Сильно | Косвенно |
Атрибуты width/height, резерв места | Нет | Нет | Сильно |
| Стратегия загрузки шрифтов | Средне | Нет | Сильно |
| Сторонние скрипты, виджеты, реклама | Средне | Сильно | Сильно |
Пороги и сам состав метрик Google периодически пересматривает: FID уже уступил место INP и больше не входит в Core Web Vitals. Не зашивайте числа в отчёты и дашборды намертво — раз в несколько месяцев сверяйтесь с актуальной документацией.

LCP: как ускорить загрузку основного контента
Largest Contentful Paint фиксирует момент, когда на первом экране отрисовался самый крупный элемент контента. Обычно это hero-изображение, обложка статьи, крупный заголовок или блок текста. Элемент может меняться по ходу загрузки: сначала LCP-кандидатом становится заголовок, потом его вытесняет картинка.
Из чего складывается LCP
Полезно разложить метрику на четыре последовательные фазы — тогда видно, где именно теряется время:
- TTFB — время до первого байта ответа. Сюда входит DNS, TCP, TLS и работа бэкенда.
- Задержка обнаружения ресурса — сколько браузер ждал, прежде чем вообще узнал про LCP-картинку. Если она подставляется скриптом или задана фоном в CSS, обнаружение откладывается.
- Загрузка ресурса — собственно скачивание файла.
- Отрисовка — время от готовности ресурса до появления пикселей на экране; здесь мешает блокирующий CSS и незавершённая загрузка шрифта.
На практике самые крупные потери обычно в первых двух фазах, а оптимизируют почему-то третью — сжимают и без того небольшую картинку.
Найдите настоящий LCP-элемент
Не угадывайте. В Chrome DevTools откройте вкладку Performance, запишите загрузку и найдите маркер LCP на таймлайне — DevTools подсветит конкретный узел DOM. Тот же элемент показывает PageSpeed Insights в блоке диагностики. Часто выясняется, что LCP — это не hero-баннер, а невидимый на первый взгляд блок текста или логотип в шапке.
Уберите задержку обнаружения
Самый дешёвый выигрыш — сказать браузеру про главный ресурс заранее и явно расставить приоритеты:
<!-- 1. Ранний коннект к домену, откуда придёт картинка -->
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<!-- 2. Предзагрузка LCP-изображения с высоким приоритетом -->
<link rel="preload" as="image" href="https://cdn.example.com/hero.avif"
imagesrcset="hero-800.avif 800w, hero-1600.avif 1600w"
imagesizes="100vw" fetchpriority="high">
<!-- 3. Сам элемент: размеры заданы, lazy НЕ ставим -->
<img src="https://cdn.example.com/hero.avif" width="1600" height="900"
alt="Описание" fetchpriority="high" decoding="async">
<!-- 4. Шрифт первого экрана: предзагрузка + swap -->
<link rel="preload" as="font" type="font/woff2"
href="/assets/fonts/inter-latin.woff2" crossorigin>
Атрибуты width и height здесь работают на две метрики сразу: браузер резервирует место (это CLS) и не пересчитывает раскладку после загрузки (это косвенно LCP).
Сократите TTFB
Ориентир — до 800 мс, но чем меньше, тем больше запаса остаётся остальным фазам. Что даёт эффект:
- Кеш готового HTML. Для анонимных посетителей отдавайте страницу из кеша, а не собирайте её заново на каждый запрос.
- CDN. Сокращает физическое расстояние до посетителя и снимает нагрузку со статики. Как это устроено — в статье что такое CDN и как он работает. Из российских площадок с CDN и облаком — например, Selectel.
- HTTP/2 или HTTP/3. Мультиплексирование убирает очередь из запросов, характерную для HTTP/1.1.
- Сжатие. Brotli для текстовых ответов заметно компактнее gzip.
- Запросы к БД. Один тяжёлый неиндексированный запрос способен съесть весь бюджет TTFB.
Измерить TTFB и общее время ответа можно одной командой:
curl -s -o /dev/null -w "dns: %{time_namelookup}s\ntls: %{time_appconnect}s\nttfb: %{time_starttransfer}s\ntotal: %{time_total}s\nsize: %{size_download} bytes\n" https://example.com/
Если разница между time_appconnect и time_starttransfer велика — проблема в бэкенде. Если велик time_namelookup — смотрите на DNS. Если раздут size_download — вероятно, не включено сжатие.
Чего делать не надо
- Не вешайте
loading="lazy"на LCP-изображение. Ленивая загрузка откладывает запрос до момента, когда браузер посчитает элемент нужным, — и метрика гарантированно ухудшается. Lazy — для того, что ниже сгиба. - Не предзагружайте всё подряд. Десять
preloadв шапке конкурируют за один канал: приоритет получают все, а значит — никто. - Не прячьте контент под анимацию появления. Если первый экран сначала прозрачный, а потом «проявляется», LCP фиксируется по факту отрисовки — и вы сами добавили себе задержку.
Более широкий разбор причин медленной загрузки — в материале почему сайт долго загружается и как это починить, а про форматы и сжатие картинок — в оптимизации изображений для веба.

INP: почему интерфейс тормозит после клика
Interaction to Next Paint измеряет, сколько проходит от действия пользователя до следующего отрисованного кадра. Учитываются клики, тапы и нажатия клавиш; прокрутка и наведение — нет. В отличие от прежнего FID, который смотрел только на первое взаимодействие и только на задержку до начала обработки, INP берёт всю сессию и репортит фактически худшее взаимодействие (на страницах с большим числом действий отбрасывается небольшая доля выбросов).
INP заменил FID в 2024 году. Практическое следствие: раньше можно было получить зелёный FID, просто отложив скрипты, — теперь метрика видит и тяжёлые обработчики, и медленный ререндер, и всё, что происходит уже после того, как страница «загрузилась».
Из чего складывается задержка
- Input delay — главный поток занят чем-то другим, событие ждёт очереди.
- Processing time — работают ваши обработчики: валидация, запросы, вычисления.
- Presentation delay — браузер пересчитывает стили, раскладку и рисует кадр.
Разбирать нужно каждую часть отдельно: сокращать обработчик бессмысленно, если проблема во входной задержке от чужого аналитического скрипта.
Что реально помогает
- Отдавайте управление главному потоку. Длинная задача (более 50 мс) блокирует реакцию на ввод. Разбивайте её на куски с явными «выдохами».
- Сначала отрисуйте отклик, потом считайте. Пользователю важно увидеть, что нажатие принято: показать спиннер или изменить состояние кнопки нужно до тяжёлой работы, а не после.
- Уносите вычисления в Web Worker. Парсинг больших JSON, сортировка тысяч строк, работа с изображениями — не дело главного потока.
- Сократите объём JavaScript. Code splitting, tree shaking, отказ от дублирующихся библиотек. Каждый килобайт JS дороже килобайта картинки: его надо ещё распарсить и выполнить.
- Держите DOM в разумных размерах. Дерево на десятки тысяч узлов делает дорогим любой пересчёт раскладки; для длинных списков используйте виртуализацию.
- Избегайте layout thrashing — чередования чтения геометрии и записи стилей в одном цикле.
Шаблон разбиения длинной задачи с возвратом управления браузеру:
// Возврат управления главному потоку между порциями работы
function yieldToMain() {
if ('scheduler' in window && 'yield' in window.scheduler) {
return window.scheduler.yield();
}
return new Promise((resolve) => setTimeout(resolve, 0));
}
async function processAll(items) {
let deadline = performance.now() + 45; // порция ~45 мс
for (const item of items) {
processOne(item);
if (performance.now() >= deadline) {
await yieldToMain(); // даём браузеру обработать ввод
deadline = performance.now() + 45;
}
}
}
Подробный разбор метрики, её субчастей и отладки — в отдельной статье про INP в Core Web Vitals.
CLS: как убрать прыжки вёрстки
Cumulative Layout Shift — единственная безразмерная метрика из трёх. Она оценивает неожиданные сдвиги уже отрисованного контента: когда кнопка уезжает вниз ровно в момент нажатия, а пользователь попадает в баннер.
Каждый сдвиг считается как произведение двух долей: сколько площади экрана затронуто и насколько далеко элементы уехали. Итоговое значение — не сумма за всю страницу целиком, а наибольшее «окно сессии»: группа сдвигов, идущих подряд с небольшими паузами. Важное следствие: CLS копится всю жизнь страницы, а не только при загрузке. Ленивая подгрузка, бесконечный скролл и всплывающие панели тоже попадают в метрику.
Сдвиги, вызванные действием пользователя, в течение примерно полусекунды после взаимодействия не учитываются — открытие аккордеона по клику метрику не портит.
Что чинить
/* 1. Резерв места под медиа: соотношение сторон вместо фиксированной высоты */
.hero img {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}
/* 2. Рекламные и встраиваемые блоки: минимальная высота до загрузки */
.ad-slot {
min-height: 280px;
contain: layout;
}
/* 3. Шрифты: fallback подобран по метрикам, чтобы подмена не двигала текст */
@font-face {
font-family: 'Inter';
src: url('/assets/fonts/inter-latin.woff2') format('woff2');
font-display: swap;
size-adjust: 105%;
ascent-override: 90%;
}
/* 4. Анимации только по composited-свойствам */
.card:hover {
transform: translateY(-4px); /* не top / margin / height */
}
Правила, которые закрывают большинство случаев:
- У каждого
<img>и<video>естьwidthиheightилиaspect-ratio. - Место под баннер, виджет отзывов или карту зарезервировано до того, как содержимое приехало.
- Ничего не вставляется над уже видимым контентом: уведомления о cookie, промо-полосы и предупреждения — в оверлей или в низ экрана.
- Шрифт-fallback подогнан по метрикам (
size-adjust,ascent-override), иначе подмена гарнитуры перекладывает абзацы. - Анимации идут через
transformиopacity, а не черезtop,heightилиmargin.
Проверять CLS только на загрузке — самая частая ошибка. Прокрутите страницу до конца, откройте меню, дождитесь ленивой подгрузки и всплывающих баннеров: у реальных посетителей метрика набирается именно там.
Лаборатория против поля: почему цифры не сходятся
Классическая ситуация: в Lighthouse 98 баллов, а в Search Console страница в красной зоне. Противоречия здесь нет — это два принципиально разных измерения.
| Признак | Лаборатория (lab) | Поле (field) |
|---|---|---|
| Источник | Lighthouse, WebPageTest, DevTools, синтетические проверки | CrUX, собственный RUM, отчёт в Search Console |
| Устройство и сеть | Заданные эмулированные условия | Реальные телефоны и реальные каналы связи |
| Взаимодействия | Нет: робот не кликает | Есть: INP без них в принципе не измеряется |
| Воспроизводимость | Высокая, удобна для отладки и CI | Низкая: статистика, а не один прогон |
| Окно данных | Мгновенный срез | Скользящее окно около 28 дней |
| INP | Не измеряется, есть суррогат (TBT) | Измеряется |
| Что показывает | Где именно проблема | Есть ли проблема у людей |
Отсюда рабочий порядок: поле отвечает на вопрос «что чинить», лаборатория — «почему это происходит». Начинать с Lighthouse без полевых данных значит оптимизировать то, что, возможно, никого не беспокоит.
Второй источник расхождений — объём данных. Если у страницы мало трафика, отдельного полевого отчёта по ней может не быть вовсе: данные агрегируются по группе похожих страниц или по всему домену. Красная зона у домена в этом случае не означает, что виновата именно та страница, которую вы открыли.
Балл производительности в Lighthouse — не Core Web Vitals. Это взвешенная сводка лабораторных метрик, включая те, которых нет в CWV. Гоняться за круглой цифрой можно бесконечно, а полевые метрики от этого не сдвинутся.

Как проверить Core Web Vitals своего сайта
Быстрый путь — прогнать страницу через проверку скорости сайта на enterno.io: инструмент показывает время загрузки, ответ сервера и узкие места, а результат можно сохранить и сравнить с предыдущим замером. Для регулярного контроля тех же страниц подойдёт мониторинг, а заголовки кеширования и сжатия удобно смотреть в проверке HTTP-заголовков.
Полевые данные
- Google Search Console, отчёт Core Web Vitals — сгруппированные по типам страниц проблемы по всему сайту. Лучший старт: показывает масштаб.
- PageSpeed Insights — полевые данные CrUX по конкретному URL плюс лабораторный прогон рядом.
- CrUX API — те же данные программно, удобно складывать в свой дашборд.
curl -s "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=$CRUX_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/","formFactor":"PHONE"}' | python3 -m json.tool
В ответе для каждой метрики придут гистограмма по трём зонам и значение 75-го перцентиля — то самое число, по которому страница считается прошедшей или нет.
Лабораторные данные
- Chrome DevTools — вкладки Performance и Lighthouse, плюс наложение Web Vitals прямо на страницу.
- Lighthouse CLI — то же самое в скрипте, годится для CI.
- WebPageTest — прогоны с разных точек и на разных профилях сети.
# Один прогон с мобильным профилем и сохранением отчёта
npx lighthouse https://example.com/ \
--only-categories=performance \
--form-factor=mobile \
--throttling-method=simulate \
--output=json --output-path=./lh.json
# Достаём ключевые метрики из отчёта
python3 - <<'PY'
import json
a = json.load(open('lh.json'))['audits']
for k in ('largest-contentful-paint', 'cumulative-layout-shift', 'total-blocking-time'):
print(k, a[k]['displayValue'])
PY
Один прогон Lighthouse не показатель: разброс между запусками на одной и той же странице легко достигает десятков процентов. Делайте три-пять прогонов и берите медиану, а в CI сравнивайте именно медианы.
Проверка вручную в браузере
Снять метрики на живой странице можно без инструментов — прямо в консоли:
// LCP: последний зафиксированный кандидат
new PerformanceObserver((list) => {
const e = list.getEntries().pop();
console.log('LCP:', Math.round(e.startTime), 'ms', e.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });
// CLS: накопленный сдвиг без учёта действий пользователя
let cls = 0;
new PerformanceObserver((list) => {
for (const e of list.getEntries()) {
if (!e.hadRecentInput) cls += e.value;
}
console.log('CLS:', cls.toFixed(3));
}).observe({ type: 'layout-shift', buffered: true });
// Длинные задачи — главный источник плохого INP
new PerformanceObserver((list) => {
for (const e of list.getEntries()) {
console.log('long task:', Math.round(e.duration), 'ms');
}
}).observe({ type: 'longtask', buffered: true });
Подборка внешних сервисов для сравнения — в обзоре лучших инструментов проверки скорости сайта.
Как собрать реальные метрики (RUM) на своём сайте
CrUX покрывает только пользователей Chrome, которые согласились на передачу статистики, и не показывает разрезы, которые нужны именно вам: по шаблону страницы, по типу трафика, по релизу. Свой RUM снимает оба ограничения.
Официальная библиотека web-vitals считает метрики так же, как их считает Chrome, и отдаёт значение, когда оно окончательно зафиксировано:
import * as webVitals from 'web-vitals';
function send(metric) {
const body = JSON.stringify({
name: metric.name, // LCP | INP | CLS | TTFB | FCP
value: Math.round(metric.value),
rating: metric.rating, // good | needs-improvement | poor
id: metric.id,
path: location.pathname,
conn: navigator.connection ? navigator.connection.effectiveType : null,
});
// sendBeacon переживает уход со страницы
if (navigator.sendBeacon) navigator.sendBeacon('/api/rum', body);
}
webVitals.onLCP(send);
webVitals.onINP(send);
webVitals.onCLS(send);
webVitals.onTTFB(send);
Что важно при своём сборе:
- Считайте перцентили, а не среднее. Среднее прячет хвост: половина пользователей может страдать, пока среднее выглядит приемлемо. Нужен минимум p75, полезен p95.
- Разрезайте по устройству. Общая цифра по сайту почти всегда маскирует провал на мобильных.
- Привязывайте к версии релиза. Иначе регрессия обнаружится через недели и без понимания, что её вызвало.
- Не собирайте лишнего. URL с параметрами, идентификаторы пользователей и содержимое форм в метриках производительности не нужны — это персональные данные, которые вы обязаны защищать без всякой пользы для замера.
Общая методика — в статье про мониторинг реальных пользователей.
Что чинить первым: от симптома к фиксу
Таблица для быстрой диагностики. Симптом берётся из отчёта, проверка — из инструмента, фикс — в код.
| Симптом | Вероятная причина | Чем проверить | Что делать |
|---|---|---|---|
| LCP плохой, TTFB большой | Медленный бэкенд, нет кеша страницы, далёкий сервер | curl -w time_starttransfer, логи приложения | Кеш HTML, CDN, индексы в БД, HTTP/2 или HTTP/3 |
| LCP плохой, TTFB нормальный | Тяжёлая картинка или позднее обнаружение ресурса | Performance в DevTools, панель диагностики PSI | AVIF/WebP, preload, fetchpriority="high", снять lazy |
| LCP скачет между прогонами | LCP-кандидатом становятся разные элементы | Несколько прогонов подряд, сравнение узла | Стабилизировать первый экран, убрать «проявление» контента |
| INP плохой при хорошем LCP | Тяжёлые обработчики, длинные задачи, сторонние скрипты | Наблюдатель longtask, вкладка Performance | Разбиение задач, Web Worker, отложить сторонние виджеты |
| INP плохой только на мобильных | Слабый процессор, тот же JS выполняется дольше | DevTools с замедлением CPU в 4–6 раз | Сократить объём JS, убрать лишние ререндеры |
| CLS плохой на загрузке | Нет размеров у медиа, подмена шрифта | Наблюдатель layout-shift, Layout Shift Regions | width/height, aspect-ratio, подгонка fallback-шрифта |
| CLS плохой при прокрутке | Ленивая подгрузка, баннеры, бесконечный скролл | Ручной проход страницы до конца | Резерв места, min-height, оверлей вместо вставки |
| Поле красное, лаборатория зелёная | Реальные устройства и сети медленнее стенда | Search Console, CrUX, свой RUM | Смотреть p75 по мобильным, а не общий балл |

Core Web Vitals и SEO: что метрики дают, а что нет
Скорость и удобство страницы Google учитывает в ранжировании — это подтверждённая часть сигналов опыта страницы. Но это один сигнал среди множества, и он не перевешивает соответствие запросу.
Что это значит на практике:
- Зелёные метрики не поднимают нерелевантную страницу. Если материал не отвечает на запрос, идеальный LCP этого не исправит.
- Плохие метрики чаще мешают, чем помогают. Красная зона — это ещё и отказы: часть посетителей уходит, не дождавшись отрисовки, и до содержимого дело не доходит.
- Эффект нелинейный. Переход из красной зоны в жёлтую обычно заметнее, чем вылизывание уже зелёной метрики с 2,1 до 1,9 с.
- Изменения видны не сразу. Полевые данные — скользящее окно примерно в четыре недели, поэтому после релиза отчёт двигается постепенно.
Никто, включая Google, не обещает конкретных позиций за улучшение Core Web Vitals. Корректная постановка задачи звучит так: убрать техническое препятствие, из-за которого часть аудитории не доходит до контента. Прирост трафика — следствие, а не гарантия.
Разумный порядок работ: сначала контент и техническое SEO (индексация, канонические адреса, корректные редиректы), затем CWV — и начинать с шаблонов страниц, на которые приходится больше всего визитов.
Типичные ошибки при оптимизации
- Оптимизация балла вместо метрик. Балл Lighthouse и Core Web Vitals — разные вещи. Ранжирование смотрит на полевые метрики.
- Замер только главной страницы. Трафик обычно приходит на карточки товаров и статьи — там другая вёрстка и другие проблемы.
- Проверка на своём железе. Быстрый ноутбук и стабильный Wi-Fi показывают картину, которой у аудитории нет. Включайте замедление CPU в DevTools.
- Ленивая загрузка «на всё сразу». Глобальный
loading="lazy"в шаблоне почти всегда цепляет и LCP-изображение. - Точечные фиксы без защиты от отката. Через два релиза кто-то вернёт виджет — и метрика уедет обратно. Нужен регулярный замер.
- Сторонние скрипты как данность. Чужие виджеты — частая причина и INP, и CLS. Их можно отложить до взаимодействия, загрузить по требованию или убрать.
- Игнорирование одной из трёх метрик. Проверка считается пройденной только по всем трём одновременно.
Как удержать результат: мониторинг и бюджет производительности
Оптимизация без контроля деградирует: новый баннер, обновление библиотеки, отключившийся кеш — и через месяц метрики там же, где были. Минимальный рабочий контур:
- Бюджет. Зафиксируйте предельные значения: LCP на ключевых шаблонах, объём JS, число сторонних доменов. Превышение — повод для обсуждения, а не для молчаливого мержа.
- Проверка в CI. Прогон Lighthouse на нескольких типовых URL с падением сборки при выходе за бюджет. Ловит очевидные регрессии до продакшена.
- Полевые метрики после релиза. Свой RUM или CrUX — с привязкой к версии.
- Внешний контроль доступности и скорости ответа. Регулярная проверка ключевых страниц через мониторинг с оповещением при росте времени ответа: чаще всего LCP уезжает не из-за вёрстки, а из-за подросшего TTFB.
Заодно проверяйте, что заголовки кеширования и сжатие на месте, — их легко потерять при переезде или смене конфигурации:
# Заголовки кеширования и сжатия для статики
curl -sI -H "Accept-Encoding: br,gzip" https://example.com/assets/app.css \
| grep -iE "cache-control|content-encoding|vary|age|etag"
# Протокол и общее время ответа для HTML
curl -s -o /dev/null -w "proto: %{http_version} ttfb: %{time_starttransfer}s\n" https://example.com/
Разложить ответ по заголовкам без консоли можно в проверке HTTP-заголовков; сравнить скорость до и после правок — в проверке скорости. Про сжатие подробно — в статье о gzip и brotli.
Частые вопросы
Какие метрики входят в Core Web Vitals
Три: LCP (скорость отрисовки главного элемента, хорошо — до 2,5 с), INP (отзывчивость на взаимодействия, до 200 мс) и CLS (визуальная стабильность, до 0,1). FID выведен из набора и заменён на INP. Набор и пороги Google периодически пересматривает.
Как проверить скорость сайта и Core Web Vitals бесплатно
Полевые данные — в отчёте Core Web Vitals в Google Search Console и в PageSpeed Insights. Лабораторные — во вкладке Lighthouse в Chrome DevTools. Быстрый замер времени загрузки и ответа сервера с сохранением результата — на странице проверки скорости enterno.io.
Какая скорость сайта считается нормальной
Ориентиры такие: TTFB до 800 мс, LCP до 2,5 с на 75-м перцентиле мобильных визитов, INP до 200 мс, CLS до 0,1. Общее «время загрузки страницы» само по себе мало о чём говорит: важно, когда появился и стал пригодным к использованию первый экран, а не когда догрузился последний скрипт аналитики.
Почему в Lighthouse 95 баллов, а в Search Console красная зона
Lighthouse — синтетический прогон на заданном профиле устройства и сети, Search Console показывает статистику реальных визитов за скользящее окно. У реальной аудитории телефоны слабее, сети хуже, а INP в лаборатории вообще не измеряется, потому что робот не кликает. Расхождение — норма; ориентироваться нужно на поле.
Через сколько после оптимизации изменятся метрики
Полевые данные обновляются с задержкой: окно наблюдения — около 28 дней, поэтому улучшение проявляется постепенно, а не на следующий день. Свой RUM показывает эффект в течение суток. Если через месяц в отчёте ничего не сдвинулось — правка, скорее всего, не затронула тот шаблон страниц, на который приходится трафик.
Влияют ли Core Web Vitals на позиции в Яндексе
Core Web Vitals — метрики Google, и в отчётах Яндекса их нет. Но скорость и стабильность страницы влияют на поведение посетителей — отказы, глубину просмотра, возвраты, — а поведенческие сигналы учитывают все поисковые системы. Работа над этими метриками полезна независимо от того, откуда приходит трафик.
Нужно ли гнаться за нулевым CLS и LCP меньше секунды
Нет. Метрики пороговые: как только страница попала в зелёную зону, дальнейшая доводка даёт заметно меньше, чем перевод в зелёную зону следующего шаблона страниц. Сначала закройте красные зоны на самых посещаемых типах страниц.
Чеклист: что проверить за один заход
- Открыт отчёт Core Web Vitals в Search Console, видно распределение по мобильным и десктопным визитам.
- Выбраны 3–5 шаблонов страниц с наибольшим трафиком — работа идёт по ним, а не по главной.
- Найден настоящий LCP-элемент на каждом шаблоне (DevTools Performance, а не догадка).
- У LCP-изображения нет
loading="lazy", естьfetchpriority="high"и заданы размеры. - TTFB измерен через
curlи укладывается примерно в 800 мс. - Включено сжатие (brotli или gzip) и корректные
Cache-Controlдля статики. - Длинные задачи найдены наблюдателем
longtask, самые тяжёлые разбиты или вынесены в Web Worker. - Сторонние скрипты инвентаризированы: отложены, загружаются по требованию или удалены.
- У всех изображений и встраиваемых блоков заданы размеры или зарезервировано место.
- Страница пролистана до конца — сдвигов при ленивой подгрузке и появлении баннеров нет.
- Настроен сбор полевых метрик (свой RUM или регулярная выгрузка CrUX) с разрезом по устройству.
- Заведён бюджет производительности и проверка в CI, чтобы регрессия не доехала до продакшена.
- Ключевые страницы стоят на мониторинге с оповещением при росте времени ответа.
Начните с замера: прогоните ключевые страницы через проверку скорости, посмотрите заголовки кеширования в проверке HTTP-заголовков и поставьте то, что важно, на мониторинг — чтобы результат оптимизации не пришлось искать заново через месяц.