Показатели Core Web Vitals
Что это такое
Три показателя, и каждый измеряет свою часть опыта загрузки и взаимодействия. Largest Contentful Paint — сколько времени занимает появление самого большого видимого элемента; Interaction to Next Paint — за сколько интерфейс отвечает на нажатие или клавишу; Cumulative Layout Shift — насколько сильно двигается контент, пока страница загружается. У каждого есть опубликованный порог, который отделяет хороший опыт от плохого.
Почему это важно
Вместе они отвечают на три вопроса, которые пользователь и задаёт: есть ли тут уже хоть что-то, отозвалось ли оно на моё касание и почему оно сдвинулось. Называть их по отдельности важно потому, что исправления разные: медленное изображение — проблема Largest Contentful Paint, тяжёлый обработчик события — Interaction to Next Paint, изображение без размеров — сдвиг макета. Команды, говорящие о «производительности» вообще, склонны оптимизировать то, что легче измерить, а не то, от чего страдает пользователь.
Ключевые идеи
Largest Contentful Paint: когда появляется основной контент
Largest Contentful Paint фиксирует время отрисовки самого большого изображения или блока текста в области просмотра. Хорошая цель — меньше 2.5 секунды. Обычные причины — медленный ответ сервера, блокирующая отрисовку таблица стилей или скрипт и слишком большое главное изображение.
<!-- главное изображение должно обнаруживаться рано, а не грузиться отложенно -->
<link rel="preload" as="image" href="/hero.avif" fetchpriority="high" />
Всё, что задерживает первую отрисовку, откладывает и его, поэтому критическая таблица стилей должна быть маленькой, а скрипты, не нужные для первой отрисовки, — отложенными.
Interaction to Next Paint: как быстро отвечает интерфейс
Interaction to Next Paint измеряет задержку между действием пользователя и ближайшим кадром, который нарисует браузер, на протяжении всего визита. Меньше 200 миллисекунд — хорошо. Показателем управляют долгие задачи в основном потоке: большой скрипт, который работает 300 миллисекунд, задержит каждое действие, пришедшее пока он идёт, даже те, что не имеют к нему отношения.
// Разбейте долгую работу, чтобы браузер успевал отрисовать между кусками
async function process(items) {
for (const item of items) {
await new Promise((r) => setTimeout(r, 0));
render(item);
}
}
Cumulative Layout Shift: сколько всего сдвигается
Cumulative Layout Shift оценивает неожиданное движение видимых элементов. Хорошо — меньше 0.1, а оценку задают несколько причин: изображения и встраиваемые блоки без объявленных размеров, шрифты, подменяющиеся на другой размер, и контент, вставленный выше того, что пользователь уже читает. Резервирование места исправляет большую часть этого.
<img src="chart.png" width="800" height="600" alt="Выручка по кварталам" />
Сдвиги, вызванные действием самого пользователя, — например, раскрытие аккордеона, по которому он кликнул, — не считаются.
Хорошо — это порог, а не градиент
Опубликованные пороги существуют, чтобы можно было принять решение: эта страница хороша или нет. Полезный вопрос — не «насколько она быстра», а «какой из трёх показателей проваливается на тех устройствах, что действительно есть у наших пользователей».
Показатели наблюдают, а не моделируют
Числа, которые считаются, собираются с настоящих сессий на настоящих устройствах, потому что именно эта совокупность и испытывает страницу. Быстрый результат на машине разработчика — гипотеза; полевые данные — ответ.
Практика
Измерьте три показателя на одной странице
Загрузите страницу, для которой есть полевые данные, или смоделируйте медленное соединение. Запишите, какой из трёх проваливается и насколько.
Готово, когда: вы можете назвать показатель, дальше всего отошедший от своего порога, и конкретный элемент или обработчик, за это ответственный.
Исправьте один показатель по его причине
Возьмите провальный показатель из предыдущего упражнения и примените единственное изменение, которое отвечает его причине: размеры у самого большого изображения, файл главного изображения поменьше или разбитая долгая задача.
Готово, когда: показатель улучшился при повторном измерении и никакой другой показатель не стал хуже.
Частые ошибки
- Оптимизация общего времени загрузки в ущерб трём показателям — страница быстро догружается, пока контент появляется поздно; исправить: измеряйте Largest Contentful Paint, а не событие load.
- Отложенная загрузка самого большого изображения первого экрана — элемент, которого ждёт показатель, намеренно отложен; исправить: грузите главное изображение сразу, с высоким приоритетом.
- Отсутствие размеров изображения — страница перестраивается по мере прихода каждого изображения, и оценка сдвига страдает; исправить: всегда объявляйте
widthиheight. - Убеждение, что быстрая машина разработчика показательна — показателями управляют устройство и сеть; исправить: измеряйте на профиле с ограничением и на настоящих полевых данных.
- Исправление одного показателя ломает другой — отложенная таблица стилей может сдвинуть контент позже; исправить: перемеряйте все три после каждого изменения.
Что читать дальше
- JavaScript (02-frontend/06-javascript) — долгие задачи и цикл событий — это то, что измеряет Interaction to Next Paint.
- Измерение и диагностика (02-frontend/26-web-performance-core-web-vitals/02-measuring-and-diagnosing) — как найти причину, а не симптом.
- Адаптивные изображения (02-frontend/07-responsive-images) — самое частое единичное исправление большого Largest Contentful Paint.