Скорость загрузки страницы: что реально влияет на метрики
LCP растёт до 4 секунд, а вы минифицируете CSS и не понимаете, почему ничего не меняется. Разбор того, что действительно двигает метрики загрузки, а что — карго-культ.

Знакомая картина: PageSpeed Insights показывает LCP 4,2 секунды на мобильном, вы включаете минификацию, добавляете defer ко всем скриптам, сжимаете картинки — и получаете 4,0 секунды. Оптимизация на 5% при затрате дня работы. Проблема в том, что вы улучшали то, что не было узким местом. Ниже — разбор того, что двигает метрики загрузки в реальных проектах и в каком порядке за это браться. Речь про современные браузеры (Chrome 120+, Firefox 120+) и метрики Core Web Vitals в редакции 2024 года.
Что вообще меряем
«Скорость загрузки» — не одно число. Пользователь и Google смотрят на три разных момента жизни страницы, и оптимизации под них не совпадают.
- LCP (Largest Contentful Paint) — когда отрисовался самый крупный видимый элемент: баннер, заголовок, главная картинка. Порог «хорошо» — до 2,5 секунд.
- INP (Interaction to Next Paint) — задержка отклика на действие пользователя. Заменил FID в марте 2024 года. Порог «хорошо» — до 200 мс.
- CLS (Cumulative Layout Shift) — насколько прыгает вёрстка во время загрузки. Порог «хорошо» — до 0,1.
Минификация CSS почти не трогает ни одну из трёх метрик на реальном сайте. А неправильно загруженный шрифт бьёт сразу по LCP и CLS. Поэтому начинать надо не с того, что проще, а с того, что в вашем случае самое медленное.
Оптимизация вслепую — это лечение симптомов. Сначала откройте вкладку Performance в DevTools и посмотрите, где реально теряются секунды. Всё остальное — гадание.
Сноска: что такое критический путь рендеринга
Критический путь рендеринга (critical rendering path) — цепочка ресурсов, которые браузер обязан загрузить и обработать, прежде чем показать первый осмысленный кадр. Обычно это HTML, блокирующий CSS и синхронный JS в <head>. Каждый лишний блокирующий ресурс в этой цепочке напрямую откладывает первую отрисовку.
Что реально двигает LCP
LCP — самая частая головная боль, и почти всегда причина в одном из четырёх мест.
1. Время до первого байта (TTFB)
Если сервер отдаёт HTML через секунду, никакая клиентская оптимизация не спасёт: LCP не может наступить раньше, чем пришёл документ. Смотрите TTFB в разделе Network. Больше 600 мс — проблема на бэкенде или в отсутствии CDN, а не во фронте. Это первое, что нужно исключить, прежде чем трогать картинки и скрипты.
2. LCP-ресурс грузится поздно
Часто самый крупный элемент — картинка, ссылка на которую браузер находит поздно: она в CSS как background-image или подставляется JavaScript. Браузер не может начать её качать, пока не распарсит стили или не выполнит скрипт. Решение — сделать ресурс видимым в HTML сразу и попросить приоритет:
<!-- Приоритетная загрузка для LCP-картинки, работает в Chrome 102+ -->
<img src="/hero.webp"
fetchpriority="high"
width="1200" height="600"
alt="Главный баннер">
<!-- Если LCP-ресурс подставляется поздно, дайте подсказку в head -->
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
Атрибуты width и height здесь заодно резервируют место и убирают сдвиг вёрстки, то есть помогают и CLS.
3. Шрифты блокируют текст
Если LCP-элемент — это текст, а шрифт грузится с задержкой, браузер либо показывает пустое место, либо ждёт. Управляется свойством font-display:
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
/* swap — показать системный шрифт сразу, заменить когда загрузится */
font-display: swap;
}
Плюс preload для основного начертания в <head>. Значение swap убирает невидимый текст, но может дать заметный «прыжок» при замене шрифта — если это критично, смотрите в сторону optional или подбора метрик системного шрифта под ваш.
4. Блокирующий CSS и JS в head
Синхронный <script> без defer в <head> останавливает парсинг HTML. Большой CSS-файл откладывает первую отрисовку. Здесь и работают знакомые советы — но эффект от них виден, только когда именно это в критическом пути.
Что двигает INP, а не LCP
INP про отзывчивость, а не про загрузку, и лечится совсем другим. Главный враг — длинные задачи в основном потоке. Пользователь нажал на кнопку, а JS в этот момент обрабатывает 200 мс сплошного кода, и клик «залипает».
Что чаще всего создаёт длинные задачи:
- тяжёлый бандл, который парсится и исполняется при старте — hydration в SPA-фреймворках;
- обработчики событий, которые синхронно делают много работы;
- сторонние скрипты: аналитика, чаты, рекламные сети.
Разбить длинную задачу можно, отдав управление браузеру между кусками работы. В современных браузерах для этого есть scheduler.yield() (Chrome 129+), но поддержка неполная — проверьте её на caniuse перед использованием в проде, для остальных браузеров нужен фолбэк.
async function processBatch(items) {
for (const item of items) {
handleItem(item);
// Отдаём поток браузеру, чтобы он успел ответить на клик.
// Проверка наличия API — не во всех браузерах есть scheduler.yield
if ("scheduler" in window && "yield" in scheduler) {
await scheduler.yield();
} else {
await new Promise((resolve) => setTimeout(resolve, 0));
}
}
}
Порядок работ: сравнение усилий и отдачи
Не все оптимизации равноценны. Ниже — грубая карта того, сколько усилий стоит приём и на что он влияет. Цифры отдачи — качественная оценка, а не замер; ваш результат зависит от того, что было узким местом до.
| Приём | На что влияет | Усилие | Типичная отдача |
|---|---|---|---|
| CDN и сжатие ответа сервера | LCP (через TTFB) | Среднее | Высокая |
fetchpriority и preload для LCP-ресурса | LCP | Низкое | Высокая |
width/height у медиа | CLS | Низкое | Высокая |
| Разбиение бандла, ленивая загрузка | INP, LCP | Высокое | Высокая |
| Отложенная загрузка сторонних скриптов | INP | Среднее | Высокая |
| font-display и preload шрифтов | LCP, CLS | Низкое | Средняя |
| Минификация CSS/JS | Размер бандла | Низкое (сборщик делает сам) | Низкая |
Когда какой приём выбирать
Критерий простой — смотрите, какая метрика красная, и лечите её причину:
- LCP красный, TTFB высокий — идите на бэкенд и в CDN, фронт вторичен.
- LCP красный, TTFB нормальный — ищите поздно загружаемый LCP-ресурс, добавляйте
fetchpriorityи preload. - INP красный — профилируйте основной поток, режьте длинные задачи и сторонние скрипты.
- CLS красный — резервируйте место под картинки, рекламу, эмбеды и поздно приходящий контент.
Где всё это ломается
Три ловушки, в которые попадают чаще всего:
- Лабораторные данные ≠ полевые. Lighthouse запускается на симуляции. Реальные пользователи с медленным телефоном и слабым каналом видят другое. Смотрите поле — CrUX или свой RUM.
- Preload всего подряд. Если пометить приоритетными десять ресурсов, приоритета не будет ни у одного: браузер потянет их разом и забьёт канал. Приоритет — для одного-двух действительно критичных.
- Оптимизация под бота. Гонитесь за 100 в PageSpeed, а не за временем до контента для живого человека. Метрика — прокси, а не цель.
Что делать дальше
Поставьте полевой мониторинг: библиотека web-vitals от команды Google собирает LCP, INP и CLS у реальных пользователей и отправляет в вашу аналитику. Так вы увидите не среднее, а 75-й перцентиль — именно по нему Google оценивает Core Web Vitals. Дальше настройте бюджет производительности в CI, чтобы новый тяжёлый скрипт не проходил ревью незаметно, и раз в спринт открывайте вкладку Performance на реальном сценарии, а не на главной. Метрика, которую стоит держать перед глазами постоянно, — INP на 75-м перцентиле: она хуже всего диагностируется по ощущениям и легче всего деградирует от очередного стороннего виджета.
Субтитры и таймкоды: Расшифровка речи и субтитры по правилам читаемости: 42 знака в строке, две строки, минимум секунда на реплику.
Спросить за 40 ₽Источники: web.dev — Core Web Vitals, MDN — Optimize long tasks
Частые вопросы
У меня другая версия Chrome, и scheduler.yield не работает — что делать?
Я всё оптимизировал, а PageSpeed всё равно показывает низкий балл. Почему?
Минификация и сжатие картинок вообще не нужны?
FID ещё используется?
Что важнее для SEO — LCP, INP или CLS?
Preload реально ускоряет или это плацебо?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.