Содержание
Performance
В вебе очень важную роль играет понятие перформанса. Чем быстрей грузится и работает сайт, тем приятней им пользоваться. Чем приятней пользоваться сайтом, тем больше у бизнеса будет клиентов и выручки.
Однако, не все сайты работают одинаково хорошо.
Ниже как раз такой пример.
Страницы выглядят похоже, но грузятся и реагируют на действия пользователя по-разному. Попробуйте нажать на кнопки ниже, чтобы запустить загрузку страниц.
Первый сайт загрузился почти мгновенно. Второй — очень долго: мы видим, как мучительно тяжело ползёт прогресс-бар и как медленно появляется контент страницы.
После загрузки сайты тоже могут вести себя по-разному. Если попытаться нажать на аккордеон в демке выше, то мы увидим, что первый сайт молниеносно реагирует на действие пользователя, а второй с явной задержкой.
Субъективно мы можем сказать, что первый сайт грузится быстро и работает отзывчиво, значит с перформансом у него все хорошо. А у второго явно есть какие-то проблемы.
Но как оценить объективно?
Web Vitals
Долгое время в индустрии не было общего решения для оценки производительности веб-страниц. Кто-то использовал кастомные метрики, другие вообще не следили за перформансом.
В мае 2020 Google предложил концепцию Web Vitals — набор метрик, с помощью которых можно оценить скорость загрузки страницы и отзывчивость интерфейса.
Web Vitals включают в себя пять метрик:
- Time To First Byte (
TTFB) - First Contentful Paint (
FCP) - Largest Contentful Paint (
LCP) - Cumulative Layout Shift (
CLS) - Interaction to Next Paint (
INP)
Помимо Web Vitals есть ещё и Core Web Vitals — набор ключевых метрик, которые лучше всего отражают производительность страницы и на которые рекомендуется смотреть в первую очередь. В их число входят: LCP, CLS и INP. Но остальные две тоже очень полезны, потому что помогают понять, на каком именно этапе начинается проблема.
Чтобы лучше понять, что обозначает каждая из метрик, предлагаю пройти весь жизненный цикл страницы и посмотреть — в какой момент будет появляться каждая из них.
Попробуйте нажать кнопку «Загрузить» в демке ниже — сработает самая первая из метрик.
TTFB
TTFB расшифровывается как Time To First Byte — время до получения первого байта ответа от сервера.
На таймлайне это выглядит так: сначала вкладка пустая, потом браузер делает запрос, проходит время, и в какой-то момент приходит ответ.
Что происходит под капотом?
Браузер запрашивает страницу. Сервер принимает запрос и начинает его обрабатывать: может сходить в базу данных, собрать все нужные данные, сформировать HTML. После этого он возвращает ответ клиенту. Уходит первый пакет, второй и так далее.
Время от старта запроса до получения первого пакета в ответ и есть TTFB.
Если сильно упростить, то TTFB складывается из двух больших частей:
- время работы на сервере;
- время доставки ответа по сети.
То есть высокий TTFB не всегда означает, что тормозит именно бэкенд. Да, иногда проблема в тяжёлой серверной логике, а иногда в сетевой задержке между пользователем и сервером.
У каждой метрики Web Vitals есть брейкпоинты, помогающие оценить состояние метрики. Для TTFB они такие:
- меньше
800ms— хорошо; - больше
1800ms— уже плохо.
Окей, ответ от сервера получили. Продолжаем загрузку.
FCP
Следующая метрика — FCP.
FCP расшифровывается как First Contentful Paint — момент, когда на странице появляется первый контент.
То есть пользователь впервые видит не просто пустой экран, а что-то осмысленное: например, заголовок, логотип, шапку, текстовый блок.
FCP отвечает на простой вопрос: когда страница вообще начала что-то показывать?
Это ещё не означает, что страница загрузилась целиком. Но это уже хороший сигнал: интерфейс ожил, и пользователь видит, что сайт действительно работает, а не завис.
Для FCP брейкпоинты такие:
- меньше
1.8s— хорошо; - больше
3s— плохо.
На FCP загрузка страницы не заканчивается, поэтому двигаемся дальше.
LCP
Дальше срабатывает LCP.
LCP расшифровывается как Largest Contentful Paint — момент, когда на странице отрисовался самый крупный контентный элемент.
Это может быть большой заголовок, крупная картинка, баннер или другой заметный по размеру блок.
Почему именно эта метрика так важна?
Пользователь приходит на сайт за ответом на свой вопрос или чтобы решить какую-то проблему. Поэтому самое важное на странице, что зачастую и является ответом на запрос пользователя, мы делаем самым заметным. Чтобы пользователь сразу увидел то, за чем он пришёл.
LCP показывает, как быстро пользователь увидел основную смысловую часть первого экрана страницы.
Для LCP пороги такие:
- меньше
2.5s— хорошо; - больше
4s— плохо.
После LCP страница может продолжать догружаться дальше: изображения, второстепенные блоки и так далее.
Если собрать всё в один таймлайн, получится довольно наглядная картина: сначала пришёл первый байт ответа, потом появился первый контент, потом отрисовался самый крупный контентный элемент, а затем страница догрузилась полностью.
Здесь может возникнуть логичный вопрос: а где CLS и INP?
Они никуда не делись. Просто не все метрики привязаны к загрузке страницы. Некоторые срабатывают уже тогда, когда страница показана пользователю и он начинает с ней взаимодействовать.
CLS
CLS расшифровывается как Cumulative Layout Shift — суммарный сдвиг макета.
Под этим подразумеваются неожиданные смещения элементов на странице. Например, пользователь уже начал читать текст или собирается нажать на кнопку, а в этот момент сверху внезапно догрузился баннер или картинка без заранее зарезервированного места. Контент сдвинулся, и интерфейс “поехал”.
Так выглядит единичный layout shift.
Но на практике проблема часто не в одном сдвиге, а в серии сдвигов.
Например, страница отрисовалась, потом по очереди догружаются картинки, и каждая из них двигает соседние элементы, потому что разработчик не задал width и height в HTML или не предусмотрел место под изображение в стилях.
В итоге браузер учитывает не один layout shift, а все такие смещения, которые произошли за время жизни страницы.
Именно поэтому CLS называется cumulative. Это сумма layout shift-ов, а не измерение одного конкретного события.
CLS измеряется числом от 0 до 1. Чем меньше, тем лучше.
- меньше
0.1— хорошо; - больше
0.25— плохо.
Если значение равно 0, значит на странице вообще не было неожиданных сдвигов. Это идеальный вариант.
А если 1 — страница целиком перерисовалась.
INP
INP расшифровывается как Interaction to Next Paint — время от интеракции пользователя до следующей отрисовки интерфейса.
В контексте INP интеракциями считаются:
- клик мышкой;
- тап на тач-устройстве;
- нажатие клавиши на клавиатуре.
Допустим, пользователь нажимает на кнопку и ждёт, пока откроется модалка.
Если интерфейс реагирует сразу, всё хорошо. Если между действием и обновлением экрана возникает заметная пауза, значит есть проблемы с отзывчивостью.
Время, прошедшее между действием пользователя и обновлением интерфейса, называется interaction latency. Чем оно меньше, тем лучше.
То же самое относится и к вводу текста. Если пользователь печатает, а символы появляются с задержкой, или интерфейс обновляется рывками, это тоже проблема отзывчивости.
Здесь так же замеряется время от действия пользователя до следующего визуального изменения интерфейса.
Если копнуть чуть глубже, interaction latency состоит из трёх частей:
input delay— событие уже произошло, но его обработка ещё не началась;processing time— исполняются обработчики события;presentation delay— обработка закончилась, но браузер ещё не дорисовал результат на экране.
Это полезно помнить при оптимизации. Если большой кусок приходится на input delay, значит главный поток был занят чем-то ещё. Если проблема в processing time, значит слишком тяжёлый код в обработчиках. Если упираемся в presentation delay, значит затык уже ближе к рендерингу.
INP считается не по одной интеракции, а как худшее значение среди всех интеракций на странице.
То есть пользователь может кликать, печатать, открывать меню, закрывать модалки, переходить по табам, а браузер будет отслеживать задержку каждой такой интеракции и в итоге возьмёт худшую.
Другими словами, INP — это время самого долгого отклика интерфейса на действие пользователя.
Для INP ориентиры такие:
- меньше
200ms— хорошо; - больше
500ms— плохо.
Итоги
Если резюмировать:
TTFBпоказывает, как быстро браузер получил ответ от сервера;FCPозначает, когда на странице появился первый контент;LCPпоказывает, когда пользователь увидел самый крупный и зачастую самый важный элемент на первом скроле;CLSотражает, насколько сильно интерфейс неожиданно сдвигался;INPозначает, насколько быстро интерфейс реагирует на действия пользователя.
Вместе эти метрики дают довольно хорошую картину того, что именно происходит со страницей: быстро ли она начинает грузиться, как скоро показывается контент, не разваливается ли по ходу загрузки и не тормозит ли при взаимодействии с UI.
Если вы только начинаете разбираться в производительности, то Web Vitals — очень хорошая точка входа. Они не отвечают вообще на все вопросы, но позволяют быстро увидеть, где у страницы слабое место и в какую сторону дальше копать.