LCP (Largest Contentful Paint) — метрика Core Web Vitals, которая измеряет время от начала загрузки страницы до момента, когда в видимой области экрана отрисован самый крупный элемент контента. Это может быть изображение, видео-постер, большой блок текста или другой DOM-элемент.
Яндекс учитывает Core Web Vitals как один из факторов ранжирования. LCP хуже 4 секунд — это «плохо» по стандартам, хуже 2,5 сек — уже требует внимания. Цель: LCP < 2,5 сек на мобильных и десктопах.
Как измерить LCP
Инструменты измерения
PageSpeed Insights (PSI) — анализирует как лабораторные данные (Lighthouse), так и полевые данные (реальные пользователи из Chrome UX Report). Для Яндекса важны именно полевые данные.
Chrome DevTools — вкладка Performance, запись загрузки страницы. LCP отмечен на таймлайне.
WebPageTest — детальный анализ с водопадом загрузки ресурсов.
Яндекс Вебмастер — раздел «Качество сайта» → Core Web Vitals показывает данные по реальным пользователям вашего сайта.
Search Console / ClickFlow — сервисы мониторинга позиций, такие как ClickFlow, позволяют коррелировать данные о Core Web Vitals с динамикой позиций в поиске, что помогает оценить реальное влияние оптимизации.
Что именно является LCP-элементом
Перед оптимизацией нужно понять, какой именно элемент является LCP на вашей странице. PSI показывает это явно. Типичные LCP-элементы:
- Hero-изображение (первый экран)
- Баннер с фоновым изображением через CSS
- Крупный заголовок H1 (если изображений нет)
- Видео-постер
Причины плохого LCP и способы устранения
1. Медленный TTFB (Time to First Byte)
LCP не может быть хорошим, если сервер долго отвечает. TTFB > 600 мс автоматически делает LCP плохим.
Решения:
- Переход на более быстрый хостинг или VPS
- Настройка кэширования на уровне сервера (Nginx FastCGI cache, Redis)
- CDN (Content Delivery Network) — ускоряет доставку статики и для геораспределённых пользователей
- Оптимизация запросов к БД (для CMS-сайтов)
Целевой TTFB: < 200 мс для «хорошего» уровня.
2. Блокирующие ресурсы (Render-Blocking Resources)
CSS и JavaScript в <head> блокируют рендеринг страницы — браузер не начинает отрисовку, пока не загрузит и не обработает эти файлы.
Решения для CSS:
- Инлайнить Critical CSS (стили для первого экрана) прямо в
<head> - Загружать остальные CSS асинхронно через
media="print"+onload - Использовать инструменты для извлечения critical CSS: Critical (npm), Penthouse
Решения для JavaScript:
- Добавляйте атрибут
deferко всем не-критичным скриптам - Атрибут
async— для аналитики и сторонних виджетов - Переносите теги
<script>в конец<body>
3. Неоптимизированные изображения
Если LCP-элемент — изображение, его размер и формат критически важны.
Современные форматы:
- WebP — на 25–35% легче JPEG при том же качестве. Поддерживается всеми современными браузерами.
- AVIF — ещё на 20–30% легче WebP. Поддержка растёт, но ещё не везде.
Реализация через тег <picture>:
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Описание" width="1200" height="600">
</picture>
Адаптивные изображения (srcset):
Не загружайте изображение 2400px для мобильного экрана 390px. Используйте srcset для подачи разных размеров в зависимости от разрешения экрана.
Сжатие:
- JPEG: качество 80–85% в большинстве случаев неотличимо от 100%
- Инструменты: Squoosh, ImageOptim, Sharp (Node.js), libvips
Размеры изображения:
Всегда указывайте атрибуты width и height на теге <img>. Это позволяет браузеру зарезервировать место до загрузки изображения и избегает CLS.
4. Отсутствие Preload для LCP-изображения
Браузер обнаруживает LCP-изображение только при парсинге HTML. Если оно загружается через CSS или JavaScript — ещё позже. Директива <link rel="preload"> сообщает браузеру загрузить ресурс как можно раньше.
<link rel="preload" as="image" href="/images/hero.webp"
imagesrcset="/images/hero-400.webp 400w, /images/hero-800.webp 800w, /images/hero-1200.webp 1200w"
imagesizes="100vw">
Важно: preload нужен именно для LCP-элемента, а не для всех изображений подряд — иначе это создаст конкуренцию за пропускную способность.
5. Lazy Loading на LCP-элементе
loading="lazy" на LCP-изображении — распространённая ошибка. Браузер откладывает загрузку «ленивых» изображений, пока страница не начнёт скроллиться. Для LCP это катастрофа.
Правило: никогда не добавляйте loading="lazy" на изображения первого экрана.
<!-- Плохо -->
<img src="hero.jpg" loading="lazy" alt="...">
<!-- Хорошо -->
<img src="hero.jpg" loading="eager" fetchpriority="high" alt="...">
Атрибут fetchpriority="high" дополнительно сообщает браузеру высокий приоритет загрузки.
6. Медленные сторонние скрипты
Скрипты аналитики, чаты, пиксели рекламы и виджеты могут существенно задерживать LCP, особенно если загружаются синхронно.
Решения:
- Загружать все сторонние скрипты с атрибутом
deferилиasync - Откладывать инициализацию не-критичных скриптов до события
loadили первого взаимодействия пользователя - Оценивать необходимость каждого стороннего скрипта (каждый добавляет задержку)
7. Рендеринг на клиенте (Client-Side Rendering)
Если сайт на React, Vue или Angular рендерится на стороне клиента, браузер получает пустой HTML и наполняет его после выполнения JavaScript. LCP откладывается до завершения этого процесса.
Решения:
- SSR (Server-Side Rendering) — сервер возвращает готовый HTML
- SSG (Static Site Generation) — страницы генерируются при деплое
- Streaming SSR — React 18+, Next.js 13+ поддерживают потоковую передачу контента
LCP и кэширование браузера
При повторных визитах браузер загружает ресурсы из кэша. Корректная настройка Cache-Control:
Cache-Control: public, max-age=31536000, immutable
Для HTML-страниц используйте более короткий TTL:
Cache-Control: public, max-age=3600
Мониторинг LCP после оптимизации
Оптимизация — не разовое действие. Сайты обновляются, появляются новые скрипты и изображения.
Настройте регулярный мониторинг:
- Яндекс Вебмастер → Core Web Vitals → ежедневная проверка
- Google Search Console (для трафика Google) — раздел Core Web Vitals
- Автоматические алерты через PageSpeed Insights API
Чек-лист улучшения LCP
- [ ] TTFB < 200 мс (проверено в PSI)
- [ ] LCP-элемент определён (что именно тормозит)
- [ ] Critical CSS инлайнится, остальные CSS — асинхронно
- [ ] Все JS-скрипты имеют defer или async
- [ ] LCP-изображение в формате WebP или AVIF
- [ ] Указаны width и height у изображений
- [ ] LCP-изображение загружается с fetchpriority="high"
- [ ] Preload добавлен для LCP-изображения
- [ ] Нет lazy loading на изображениях первого экрана
- [ ] Сторонние скрипты загружаются асинхронно
- [ ] Кэширование настроено корректно
- [ ] Мониторинг Core Web Vitals настроен
Итог
LCP — наиболее весомая метрика из трёх Core Web Vitals с точки зрения воспринимаемой скорости загрузки. Большинство проблем с LCP решается последовательно: сначала TTFB, затем блокирующие ресурсы, затем оптимизация изображений. Систематический подход позволяет достичь LCP < 2,5 сек даже на ресурсоёмких сайтах.