Инструменты измерения

Четыре инструмента, троттлинг и умение читать водопад — этого достаточно, чтобы за полчаса назвать точную причину медленной страницы.

Водопад загрузки (waterfall) — диаграмма, где каждый запрос показан полоской: когда он начался, сколько ждал и сколько качался. По форме «лестницы» сразу видно, что браузер узнал о ресурсе слишком поздно.

Зачем несколько инструментов

Каждый отвечает на свой вопрос, и подменять один другим — верный способ починить не то. Lighthouse говорит «что вообще не так» и даёт список гипотез. Network показывает «что и когда грузилось». Performance — «чем был занят главный поток». WebPageTest — «а как оно выглядит на настоящем телефоне из Мумбаи». Дальше — по порядку.

Lighthouse: быстрый первый диагноз

Живёт в трёх местах: во вкладке Lighthouse в DevTools, на PageSpeed Insights (там же рядом покажут полевой CrUX) и в консоли как npm-пакет. Для регулярной работы берите консоль — её можно повторить и поставить в CI.

# одиночный прогон с отчётом в браузере
npx lighthouse https://example.com/catalog --view

# мобильный профиль (по умолчанию) + JSON для автоматики
npx lighthouse https://example.com/catalog \
  --output=json --output-path=./lh-mobile.json --quiet

# десктопный профиль: другое разрешение и другой троттлинг
npx lighthouse https://example.com/catalog --preset=desktop --view

# 5 прогонов: одиночный слишком шумит, берём медиану
for i in 1 2 3 4 5; do
  npx lighthouse https://example.com/catalog \
    --output=json --output-path=./run-$i.json --quiet
done

Что читать в отчёте: не балл, а два блока. Opportunities — гипотезы с оценкой экономии («Preload the LCP image — 1,2 s»). Diagnostics — факты: сколько весит JS, какие задачи длинные, какой элемент оказался LCP. И обязательно раскройте LCP-разбивку по фазам — она сразу отсекает половину направлений поиска.

Помните ограничение из прошлого урока: Lighthouse загружает страницу и ничего в ней не нажимает, поэтому INP он не измеряет. Отзывчивость проверяем руками в Performance.

DevTools: Network и водопад

Открываем вкладку Network, ставим три галочки, без которых измерение бессмысленно: Disable cache (пользователь приходит впервые), профиль сети Slow 4G и CPU-троттлинг (о нём ниже). Перезагружаем.

Каждая полоска в водопаде — это фазы запроса, и по их цвету видно, где потеря:

ФазаЧто происходитО чём говорит, если длинная
Queueing / Stalledзапрос ждёт своей очередиупёрлись в лимит соединений или низкий приоритет
DNS / Initial connection / SSLустановка соединениялишний домен, нет preconnect
Waiting (TTFB)сервер думаетбэкенд, база, промах кеша CDN
Content Downloadкачаются байтыресурс просто тяжёлый

Теперь главное — как читать саму картинку. Вот типичный водопад медленной карточки товара, записанный на Slow 4G:

#  Ресурс                          Старт    Длит.   Фазы
1  GET /product/42  (document)        0 ms   540 ms  TTFB 480 | download 60
2  GET /assets/app.a1b2.css         560 ms   240 ms  render-blocking
3  GET /assets/app.c3d4.js          560 ms   980 ms  defer, 310 КБ
4  GET /fonts/inter.woff2           840 ms   190 ms  обнаружен из CSS
5  GET /api/product/42             1560 ms   620 ms  запущен из JS
6  GET /img/hero-1200.jpg          2210 ms   900 ms  ← ЭЛЕМЕНТ LCP

   FCP  = 820 ms
   LCP  = 3110 ms   (плохо)

Разбираем. Строки 2 и 3 стартуют одновременно — это хорошо, оба ресурса нашлись в HTML. А дальше начинается лестница: шрифт узнали только из CSS (840 мс), запрос к API запустился только после того, как выполнился JS (1560 мс), а картинка героя — та самая, что и есть LCP, — обнаружилась только после ответа API (2210 мс). Каждая «ступенька» — это цепочка зависимостей: браузер физически не мог начать раньше, потому что не знал об этом ресурсе.

Вывод из водопада однозначный: LCP = 3110 мс, из которых 2210 мс картинка просто ждала, пока о ней узнают. Загрузка самой картинки (900 мс) — вторая по важности проблема. Чинить надо не «оптимизировать сайт», а: отдать адрес картинки прямо в HTML (или preload с fetchpriority="high") и не гнать данные для первого экрана через клиентский API-запрос. Ровно это и значит «измеряй, а не гадай»: водопад назвал причину, а не вы её угадали.

Полезная привычка: включите в Network колонку Priority и сравните приоритет LCP-картинки с приоритетом какого-нибудь баннера. Часто оказывается, что браузер считает главную картинку менее важной, чем логотип в подвале.

DevTools: Performance

Network показывает сеть, но INP и длинные задачи живут в главном потоке. Вкладка Performance — про него.

Два сценария. Первый: запись загрузки (кнопка перезагрузки со стрелкой) — получите таймлайн с дорожками Timings (там отметки FCP, LCP, DCL) и Main. Второй, который забывают: запись взаимодействия. Нажимаете запись, кликаете по тяжёлому фильтру, останавливаете — и в дорожке Interactions видите то самое взаимодействие с его длительностью, а под ним flame chart: чьи именно обработчики съели 700 мс. Это единственный способ отладить INP локально; в современных версиях Chrome панель Performance ещё и показывает живые локальные LCP / CLS / INP прямо во время работы со страницей.

Что ищем на дорожке Main: длинные задачи — блоки дольше 50 мс, Chrome помечает их красным уголком. Пока такая задача выполняется, браузер не может ни ответить на клик, ни нарисовать кадр. Длинные задачи — прямая причина плохого INP и косвенная — плохого LCP.

Троттлинг: без него все числа врут

Троттлинг — искусственное замедление CPU и сети до уровня, похожего на реальный телефон. Без него вы измеряете свой ноутбук.

  • CPU 4x — примерный уровень среднего Android. 6x — бюджетного. Разница огромна: JS, который на вашей машине парсится 80 мс, на телефоне съест полсекунды.
  • Slow 4G в DevTools — это около 400 мс задержки (RTT) и примерно 1,6 Мбит/с на приём. Fast 4G — 150 мс и порядка 9 Мбит/с. Начинайте со Slow 4G: если на нём хорошо, то хорошо у всех.
  • Обязательно Disable cache — метрики Core Web Vitals в поле складываются в основном из первых визитов.

Тонкость, которая объясняет вечный вопрос «почему в Lighthouse LCP 3,4 с, а в Network водопад заканчивается за 2 с». У троттлинга две реализации. Simulated (по умолчанию в Lighthouse, движок Lantern): страница грузится на полной скорости, а замедление МОДЕЛИРУЕТСЯ математически поверх записанного таймлайна — быстро и стабильно, но это оценка. Provided / applied (DevTools): пакеты реально задерживаются, процессор реально душится — медленнее, зато честно.

# не моделировать, а реально душить сеть и CPU — числа ближе к DevTools
npx lighthouse https://example.com/catalog \
  --throttling-method=provided \
  --view

Правило простое: сравнивайте числа только внутри одного метода троттлинга. Сравнивать LCP из Lighthouse с LCP из DevTools — сравнивать килограммы с километрами.

WebPageTest: когда нужна настоящая среда

Локальные инструменты эмулируют телефон. WebPageTest даёт настоящий: реальные устройства в реальных локациях. Что берём оттуда, чего нет больше нигде:

  • Filmstrip и видео — покадровая лента загрузки. Ничто так не отрезвляет команду, как 5 секунд белого экрана на записи.
  • Repeat View — второй визит с прогретым кешем. Показывает, работает ли ваша стратегия кеширования.
  • Connection View — что происходило на уровне соединений: сколько их открылось, сколько времени ушло на TLS.
  • Медиана из 3–9 прогонов — сразу, из коробки, без вашего цикла в bash.
  • Локации: страница из Москвы и из Джакарты — это две разные страницы.

Как это работает

Все инструменты в итоге читают одни и те же данные из движка браузера: Chrome ведёт трассу событий (trace), а Performance API отдаёт из неё уже посчитанные метрики. Lighthouse — это, по сути, автоматизированный сценарий поверх Chrome DevTools Protocol: он запускает браузер, включает эмуляцию мобильного экрана и троттлинг, загружает страницу, собирает трассу и прогоняет по ней набор аудитов. Поэтому у него нет никакой «магии»: всё, что он говорит, вы можете увидеть руками в DevTools — просто он делает это быстрее и в одном отчёте.

Отсюда практический порядок работы, который экономит часы:

  1. Поле (CrUX или свой RUM) — какая страница и какая метрика плохи.
  2. Lighthouse на этой странице с мобильным профилем — список гипотез и разбивка LCP по фазам.
  3. Network с водопадом — точная причина: поздно обнаружен ресурс, тяжёлый ресурс или медленный TTFB.
  4. Performance — если проблема в JS: длинные задачи, INP на конкретном взаимодействии.
  5. Правка → повторный замер тем же инструментом и с тем же троттлингом → выкат → проверка в поле.

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

  • Мерить без троттлинга. Самая частая и самая дорогая ошибка: вы получаете отчёт о своём ноутбуке.
  • Мерить с включёнными расширениями браузера. Блокировщики и дев-тулзы фреймворков искажают и время, и водопад. Используйте режим инкогнито или чистый профиль (Lighthouse CLI так и делает).
  • Забыть Disable cache. На втором прогоне всё летает, потому что половина ресурсов уже лежит в кеше — и вы делаете вывод, что всё хорошо.
  • Сравнивать несравнимое. LCP из Lighthouse (simulated) и LCP из DevTools (applied) — разные числа по построению.
  • Верить одному прогону. Шум 15–20% нормален. Три-пять прогонов, медиана.
  • Читать в водопаде только длину полосок. Форма важнее длины: «лестница» из ступенек — это цепочка зависимостей, и она обычно стоит дороже, чем пара тяжёлых файлов.
  • Искать INP в Lighthouse. Его там нет. Нажимайте руками с CPU 4x и смотрите Performance.

Итоги

  • Lighthouse — первый диагноз и гипотезы; читайте Opportunities, Diagnostics и разбивку LCP, а не балл.
  • Network показывает водопад: «лестница» означает, что ресурс обнаружен поздно, и это чаще всего и есть причина плохого LCP.
  • Performance — про главный поток: длинные задачи (дольше 50 мс) и запись реального взаимодействия для отладки INP.
  • WebPageTest — настоящие устройства, локации, filmstrip и повторный визит с прогретым кешем.
  • Троттлинг обязателен: Slow 4G + CPU 4x. Simulated (Lighthouse) и applied (DevTools) дают разные числа — не сравнивайте их между собой.
  • Порядок работы: поле → Lighthouse → водопад → Performance → правка → повторный замер → поле.
Проверьте себя
1. В водопаде видно: HTML пришёл за 540 мс, CSS и JS стартовали сразу, а LCP-картинка начала грузиться только на 2210-й миллисекунде — после ответа API, который запустил JS. Что чинить в первую очередь?
AСжать картинку сильнее — 900 мс на загрузку это много
BУскорить бэкенд: TTFB 480 мс — главная потеря
CСделать так, чтобы браузер узнал о картинке из HTML сразу (preload / fetchpriority) и не ждал API — сейчас теряется больше двух секунд на одном лишь обнаружении
DУбрать шрифт: он грузится из CSS и блокирует картинку
2. Почему LCP из Lighthouse (по умолчанию) и LCP из панели Network в DevTools обычно не совпадают?
ALighthouse считает LCP от события load, а DevTools — от начала навигации
BLighthouse по умолчанию использует simulated-троттлинг: он моделирует замедление математически, а DevTools реально задерживает пакеты и душит CPU
CDevTools не учитывает CPU-троттлинг, поэтому всегда показывает меньшее значение
DLighthouse измеряет LCP на десктопном профиле, а DevTools — на мобильном