Скорость сайта влияет на удобство реальных пользователей, но одна лабораторная оценка Lighthouse не описывает их опыт полностью. Для приоритизации улучшений сопоставляйте полевые данные Core Web Vitals, устройства и ключевые пользовательские сценарии.
Разберём подходы к оптимизации LCP, CLS и загрузки JavaScript в Next.js, а также границы каждого измерения.
Ключевые метрики Core Web Vitals и цели оптимизации
| Метрика | Значение | Описание | Целевой показатель |
|---|---|---|---|
| FCP (First Contentful Paint) | Первая отрисовка контента | Время появления первого элемента (текста или логотипа) | < 1.0 сек |
| LCP (Largest Contentful Paint) | Отрисовка основного контента | Время загрузки самого крупного видимого блока (обычно баннер в Hero) | < 1.5 сек |
| TBT (Total Blocking Time) | Общее время блокировки | Суммарное время выполнения блокирующих скриптов во время загрузки | < 150 мс |
| CLS (Cumulative Layout Shift) | Накопительный сдвиг макета | Стабильность верстки, отсутствие неожиданных прыжков контента | 0 (идеально) |
1. Оптимизация Largest Contentful Paint (LCP)
В 90% случаев элементом LCP на главной странице является изображение в первом блоке (Hero image).
Использование priority
Указывайте атрибут priority для изображений первого экрана. Это заставит браузер загружать картинку в первую очередь, игнорируя ленивую загрузку:
import Image from 'next/image';
export function HeroBanner() {
return (
<Image
src="/hero-banner.webp"
alt="Разработка сайтов EvaLab"
width={1200}
height={630}
priority
sizes="(max-width: 768px) 100vw, 1200px"
/>
);
}
Задание размеров (sizes)
Всегда прописывайте атрибут sizes. Без него Next.js сгенерирует srcset, но браузер не будет знать размеры на разных экранах и скачает полноразмерную картинку на мобильный телефон.
2. Снижение Total Blocking Time (TBT)
Главный враг TBT — тяжелые сторонние скрипты (аналитика, онлайн-консультанты, пиксели соцсетей) и избыточный JS на клиенте.
Динамический импорт виджетов
Загружайте виджеты поддержки, карты и формы только при необходимости (по клику, скроллу или с задержкой).
Пример отложенной загрузки в Next.js:
import dynamic from 'next/dynamic';
const AIAssistantWidget = dynamic(
() => import('@/components/AIAssistantWidget').then((mod) => mod.AIAssistantWidget),
{ ssr: false } // отключаем SSR для чисто клиентских виджетов
);
Использование next/script с worker
Для Я.Метрики и Google Analytics используйте компонент Script с типом загрузки lazyOnload или переносите их выполнение в Web Workers через PartyTown:
import Script from 'next/script';
<Script
src="https://mc.yandex.ru/metrika/tag.js"
strategy="lazyOnload"
/>
3. Устранение Cumulative Layout Shift (CLS)
Сдвиги макета раздражают пользователей и пессимизируются поисковыми роботами.
- Резервируйте место под баннеры и шрифты: Задавайте фиксированную высоту для блоков-контейнеров, содержимое которых подгружается асинхронно.
- Шрифты: Используйте ext/font` для автоматической оптимизации Google Fonts. Он генерирует резервный шрифт с рассчитанными размерами (size-adjust), чтобы при переключении на основной шрифт текст не прыгал.
Ограничение измерений
Lighthouse полезен для поиска технических проблем, но его результат не является гарантией быстрой работы для всех посетителей. Сверяйте лабораторный тест с полевыми показателями Web Vitals и тестируйте критичные сценарии на целевых устройствах. Связанный материал: как измерять эффективность B2B-сайта.
Резюме
Достижение 100/100 в Lighthouse на Next.js — это результат системной гигиены кода. Оптимизируйте изображения первого экрана с помощью priority, откладывайте загрузку сторонних скриптов с помощью dynamic() и избегайте динамических сдвигов макета. Это сделает ваш сайт не только быстрым для роботов, но и удобным для живых пользователей.
Ведущий инженер и разработчик веб-систем. Специализируется на Next.js, чистой архитектуре, Core Web Vitals и алгоритмическом ранжировании.


