Вы подняли проект с нуля, выполнили все бизнес-требования и запустили в формате MVP, всё работает, но бизнес или пользователи жалуются, что сайт подтупливает. Вы открываете прод на своем MacBook Pro на последнем М-процессоре — всё летает. Где же проблема? Чтобы разобраться, пригодятся знания о Core Web Vitals — трёх главных метриках, которые использует в том числе и Google для оценки скорости и удобства вашего сайта.
- Что такое Core Web Vitals?
- На примере шаурмы
- LCP: Скорость загрузки основного контента
- Что считается «самым большим элементом»?
- Хороший, плохой, критический
- Почему LCP важен?
- Как улучшить LCP?
- FID: Отзывчивость на первое взаимодействие
- Почему мы измеряем FID, а не TTI (Time to Interactive)?
- Хороший, плохой, критический
- Почему FID важен?
- Как улучшить FID?
- CLS: Визуальная стабильность
- Как измеряется CLS?
- Хороший, плохой, критический
- Почему CLS важен?
- Как улучшить CLS?
- Как измерять Core Web Vitals?
- Инструменты для измерения
- Измеряем в реальном времени
- Что можно сделать для улучшения Core Web Vitals прямо сейчас
- LCP
- FID
- CLS
- Итоги
Что такое Core Web Vitals?
Core Web Vitals — это три метрики, которые Google считает самыми важными для пользовательского опыта:
- LCP (Largest Contentful Paint) — скорость загрузки основного контента.
- FID (First Input Delay) — отзывчивость на первое взаимодействие.
- CLS (Cumulative Layout Shift) — визуальная стабильность.
С июля 2021 года эти метрики влияют на SEO — сайты с плохими показателями ранжируются ниже в поисковой выдаче Google.
На примере шаурмы
Снова представим ларек с шаурмой, владелец которого хочет увеличить эффективность бизнеса и для этого, начитавшись умных книжек и блогов, решает отслеживать Core Web Vitals.
В таком случае:
- LCP (Largest Contentful Paint) — время, за которое на стол попадает главное блюдо из заказа. Если его долго не несут — посетитель нервничает.
- FID (First Input Delay) — время от того, как посетитель попросил добавить в заказ лимонад, до того, как работник потянулся к холодильнику. Если он завис — посетитель напрягается.
- CLS (Cumulative Layout Shift) — насколько стабилен стол. Если посетитель тянется за купленным лимонадом, а стол внезапно наклоняется, он может пролить напиток и поставить низкую оценку заведению.
LCP: Скорость загрузки основного контента
LCP — время от начала загрузки страницы до момента, когда отобразился самый большой элемент в области просмотра (видимой части экрана).
Что считается «самым большим элементом»?
- Изображение (
<img>) - Видео-превью (
<video>) - Элемент с фоновым изображением (через CSS
background-image) - Блочный элемент с текстом (
<div>,<p>)
Хороший, плохой, критический
| Показатель | Оценка |
|---|---|
| ≤ 2.5 секунды | 🟢 Хорошо |
| 2.5 — 4 секунды | 🟡 Требует улучшения |
| > 4 секунды | 🔴 Плохо |
Почему LCP важен?
Пользователь не ждет, пока загрузится вся страница. Ему нужно увидеть основное содержание (заголовок, картинку, кнопку «Купить»). Если этого нет через 2-3 секунды — он склонен уйти.
Как улучшить LCP?
1. Оптимизируйте изображения
<!-- Используйте современные форматы -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Описание">
</picture>
- Используйте WebP или AVIF (они легче JPG/PNG на 30-50%)
- Сжимайте изображения (TinyPNG, Squoosh)
2. Удалите блокирующие скрипты
<!-- Скрипты, которые не нужны для первого экрана, загружайте асинхронно -->
<script src="analytics.js" async></script>
<script src="heavy-widget.js" defer></script>
async— скрипт загружается параллельно, выполняется сразуdefer— скрипт загружается параллельно, выполняется после загрузки HTML
3. Используйте CDN
Раздавайте статику (картинки, CSS, JS) через CDN. Файлы будут ближе к пользователю.
4. Включите кэширование
Cache-Control: max-age=31536000, immutable
Статические файлы кэшируются на год. Пользователь загружает их один раз.
5. Перенесите CSS-критические стили в <head>
<head>
<style>
/* Только стили для первого экрана */
.header { background: #fff; }
.hero { font-size: 2rem; }
</style>
<!-- Остальные стили загружаем асинхронно -->
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
</head>
FID: Отзывчивость на первое взаимодействие
FID — время от момента первого взаимодействия пользователя со страницей (клик, нажатие клавиши, касание) до момента, когда браузер начинает обрабатывать это событие.
Почему мы измеряем FID, а не TTI (Time to Interactive)?
Потому что пользователь может начать взаимодействовать до того, как страница полностью загрузилась. FID измеряет задержку именно для первого взаимодействия.
Хороший, плохой, критический
| Показатель | Оценка |
|---|---|
| ≤ 100 мс | 🟢 Хорошо |
| 100 — 300 мс | 🟡 Требует улучшения |
| > 300 мс | 🔴 Плохо |
Почему FID важен?
Представьте: вы кликаете на кнопку «Добавить в корзину», а она не реагирует 3 секунды. Вы кликаете еще раз, потом еще, потом не перепроверив корзину оформляете заказ. Итог: лишние клики, лишние товары в заказе, а вы в «восторге» от предстоящего общения со службой поддержки.
Как улучшить FID?
1. Разбивайте длинные задачи
Если у вас есть скрипт, который выполняется 200+ мс, он блокирует основной поток. Браузер не может реагировать на клики.
// Плохо — 300 мс блокировки
function heavyCalculation() {
for (let i = 0; i < 1000000000; i++) {
// тяжелые вычисления
}
}
// Хорошо — разбиваем на мелкие части
function heavyCalculation() {
let i = 0;
const chunkSize = 1000;
const results = [];
function chunk() {
const nextChunk = data.slice(i, i + chunkSize);
if (nextChunk.length === 0) {
return results;
}
// Обработка текущего чанка
for (const item of nextChunk) {
results.push(
// Здесь выполняем необходимые операции над item
);
}
i += chunkSize;
// Передаем управление браузеру
setTimeout(chunk, 0);
}
chunk();
}
Используйте setTimeout, requestIdleCallback или Web Workers для тяжелых задач.
2. Не загружайте тяжелый JS на первый экран
// Загружаем тяжелый виджет только после того, как страница стала интерактивной
window.addEventListener('load', () => {
import('./heavy-widget.js').then(module => {
module.init();
});
});
3. Удалите ненужные полифиллы
Для старых браузеров используйте полифиллы. Но не тащите их в те браузеры, которые уже поддерживают необходимую функциональность.
// Загружаем полифилл только если он нужен
if (!('IntersectionObserver' in window)) {
import('intersection-observer');
}
CLS: Визуальная стабильность
CLS — суммарный сдвиг макета. Измеряет, насколько «прыгает» контент на странице в процессе загрузки.
Как измеряется CLS?
Браузер отслеживает каждый раз, когда видимый элемент меняет свою позицию. Чем больше сдвиг и чем больше элемент — тем выше «штраф».
Хороший, плохой, критический
| Показатель | Оценка |
|---|---|
| ≤ 0.1 | 🟢 Хорошо |
| 0.1 — 0.25 | 🟡 Требует улучшения |
| > 0.25 | 🔴 Плохо |
Почему CLS важен?
Вы читаете статью, внезапно страница дергается, вы теряете строчку, на которую смотрели. Или вы хотите нажать на кнопку, а она «убегает» вниз — вы кликаете на рекламу вместо кнопки.
Как улучшить CLS?
1. Всегда указывайте размеры изображений и видео
<!-- Плохо — картинка подпрыгнет, когда загрузится -->
<img src="image.jpg" alt="Котик">
<!-- Хорошо — браузер знает, сколько места оставить -->
<img src="image.jpg" alt="Котик" width="800" height="600">
2. Зарезервируйте место под рекламу и iframe
<!-- Если не знаете точную высоту, зарезервируйте минимум -->
<div style="min-height: 250px;">...</div>
3. Не вставляйте контент сверху уже загруженного
Если вы динамически добавляете элементы в начало страницы (например, баннер о куках или pop-up), используйте position: fixed или position: sticky.
/* Баннер, который не сдвигает контент */
.cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
4. Используйте CSS-свойство aspect-ratio
.image-container {
aspect-ratio: 16 / 9;
background: #f0f0f0; /* скелетон */
}
Браузер зарезервирует место еще до загрузки картинки.
5. Не используйте шрифты с изменяемой высотой
Некоторые шрифты при загрузке меняют высоту строк, что вызывает сдвиги. Используйте font-display: optional или font-display: swap.
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2');
font-display: swap; /* Пока шрифт не загрузился, покажем системный */
}
Как измерять Core Web Vitals?
Инструменты для измерения
| Инструмент | Для чего |
|---|---|
| Google PageSpeed Insights | Анализ страницы + рекомендации |
| Lighthouse (в DevTools) | Локальный аудит |
| Chrome DevTools (вкладка Производительность) | Детальный профилинг |
| Web Vitals (библиотека) | Сбор метрик в реальном времени |
| Google Search Console | Core Web Vitals для всех страниц сайта |
Измеряем в реальном времени
// Устанавливаем библиотеку
import { getLCP, getFID, getCLS } from 'web-vitals';
// Отправляем в аналитику
function sendToAnalytics({ name, value }) {
console.log(`${name}: ${value}`);
// Отправка в Google Analytics / Яндекс.Метрику
}
getLCP(sendToAnalytics);
getFID(sendToAnalytics);
getCLS(sendToAnalytics);
Что можно сделать для улучшения Core Web Vitals прямо сейчас
LCP
- Изображения в WebP/AVIF
- Сжатие изображений
- Асинхронная загрузка скриптов
- CDN и кэширование
- Критический CSS в
<head>
FID
- Разбивка длинных задач
- Ленивая загрузка JS
- Минификация JS
- Удаление полифиллов для современных браузеров
CLS
- Указаны размеры всех изображений
- Зарезервировано место под рекламу
- Используется
aspect-ratio font-display: swap- Динамический контент добавляется стабильно
Итоги
Пользователь не прощает долгой загрузки. Каждые 100 мс задержки снижают конверсию на 1%. Каждые 2 секунды — на 10%. Оптимизируйте Core Web Vitals — и пользователи скажут вам спасибо. Желаю успехов!







