Оптимизация скорости сайта в 2026 году — как достичь Core Web Vitals 90+
Полное руководство 2026 года по оптимизации Google Core Web Vitals. Рассматривает измерение и улучшение LCP, INP и CLS: оптимизацию изображений (WebP/AVIF), предварительную загрузку шрифтов, разделение JavaScript-бандлов, настройку CDN. Включает чек-лист из 30 пунктов для достижения Lighthouse 90+ с примерами кода для Next.js.
> **Краткое резюме** Google Core Web Vitals в 2026 году: LCP (Largest Contentful Paint) < 2.5s, INP (Interaction to Next Paint) < 200ms, CLS (Cumulative Layout Shift) < 0.1. Эти три метрики напрямую влияют на позиции в поисковой выдаче Google. Оптимизации с наибольшим эффектом: ① преобразование изображений в WebP/AVIF ② предварительная загрузка шрифтов ③ разделение JavaScript-кода ④ развертывание на edge-узлах CDN. Пользователи Next.js могут достичь Lighthouse 90+ при правильной стандартной конфигурации.
Что такое Core Web Vitals?
Core Web Vitals — это три основные метрики пользовательского опыта Google, включенные в сигналы ранжирования SEO с 2021 года.
Три ключевые метрики
| Метрика | Полное название | Что измеряет | Хорошо | Требует доработки | Плохо |
|---|---|---|---|---|---|
| **LCP** | Largest Contentful Paint | Время отрисовки самого крупного изображения или текстового блока | < 2.5s | 2.5–4s | > 4s |
| **INP** | Interaction to Next Paint | Время от клика пользователя до визуального отклика | < 200ms | 200–500ms | > 500ms |
| **CLS** | Cumulative Layout Shift | Неожиданное смещение макета во время загрузки | < 0.1 | 0.1–0.25 | > 0.25 |
Примечание: FID (First Input Delay) был заменен на INP в 2024 году.
Почему Core Web Vitals важны
**Прямое влияние на SEO**: Учитываются в алгоритме ранжирования Google — при одинаковом контенте выигрывает более быстрый сайт
**Показатель отказов**: LCP > 3s увеличивает показатель отказов на мобильных устройствах на 53% (исследование Google)
**Доход от рекламы**: AdSense RPM коррелирует со временем на странице → более быстрый сайт = выше RPM
**Конверсия**: задержка в 1 секунду = падение конверсии на 7% (исследование Akamai)
Оптимизация LCP
LCP обычно определяется временем загрузки hero-изображения или самого крупного текстового блока.
Оптимизация изображений (наибольший эффект)
**Сравнение форматов:**
| Формат | Уменьшение размера | Поддержка браузерами |
|---|---|---|
| JPEG | Базовый уровень | 100% |
| WebP | на 25–35% меньше | 98%+ |
| AVIF | на 40–50% меньше | 90%+ (2026) |
```html
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Hero image" width="1200" height="628" loading="eager">
</picture>
```
**Компонент Image в Next.js:**
```typescript
import Image from 'next/image'
// LCP images must have priority prop
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={628}
priority // critical — eliminates LCP delay
quality={85}
/>
```
Предварительная загрузка ресурсов
```html
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
<link rel="preload" as="font" href="/fonts/main.woff2" type="font/woff2" crossorigin>
```
Время ответа сервера (TTFB)
| Метод | Влияние | Реализация |
|---|---|---|
| CDN | Глобальное edge-кэширование | Cloudflare, Vercel Edge |
| Заголовки кэша | Мгновенная загрузка для вернувшихся посетителей | Cache-Control: max-age=31536000 |
| SSG/ISR | Предварительно сгенерированный HTML | Next.js generateStaticParams |
Оптимизация INP
INP измеряет время от любого взаимодействия пользователя (клик, касание, ввод с клавиатуры) до момента, когда браузер отрисует следующий кадр.
Уменьшение блокировки основного потока
```javascript
// Bad: heavy sync computation blocks click response
button.addEventListener('click', () => {
const result = heavyComputation(data) // blocks main thread
updateUI(result)
})
// Good: offload to Web Worker
const worker = new Worker('heavy-worker.js')
button.addEventListener('click', () => {
worker.postMessage(data) // runs in separate thread
})
worker.onmessage = (e) => updateUI(e.data)
```
Разделение кода (Next.js)
```typescript
import dynamic from 'next/dynamic'
// Defer components not visible on first load
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <div>Loading chart...</div>,
ssr: false
})
```
Tree Shaking
```javascript
// Bad: imports entire lodash (70KB+)
import _ from 'lodash'
// Good: imports only what you need (1KB)
import chunk from 'lodash/chunk'
```
Оптимизация CLS
CLS возникает, когда реклама, изображения или динамический контент меняют положение во время загрузки.
Всегда указывайте размеры изображений
```html
<img src="photo.jpg" width="800" height="600" alt="photo">
<img src="photo.jpg" alt="photo">
```
Резервируйте место для рекламы
```css
.ad-container {
min-height: 250px; /* pre-reserve ad space */
display: flex;
align-items: center;
justify-content: center;
}
```
Загрузка шрифтов
```css
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap; /* show system font immediately, swap when loaded */
}
```
Чек-лист Lighthouse 90+ (30 пунктов)
**LCP (10 пунктов)**
[ ] Определить LCP-элемент (DevTools → вкладка Performance)
[ ] Добавить priority или preload для LCP-изображения
[ ] Преобразовать hero-изображение в WebP/AVIF
[ ] Использовать next/image для автоматической оптимизации
[ ] Предоставить адаптивные изображения через srcset
[ ] Использовать CDN (Cloudflare Pages, Vercel Edge)
[ ] Проверить, что TTFB < 600ms
[ ] Использовать SSG/ISR там, где возможно
[ ] Удалить ненужные редиректы
[ ] Отложить загрузку всех сторонних скриптов
**INP (10 пунктов)**
[ ] Проверить показатель INP в Lighthouse
[ ] Удалить Long Tasks (50ms+) — вкладка Performance в DevTools
[ ] Перенести тяжелые вычисления в Web Workers
[ ] JavaScript-бандл < 200KB (в сжатом виде)
[ ] Удалить ненужные полифилы
[ ] Применять useMemo/useCallback в React
[ ] Использовать debounce/throttle для обработчиков событий
[ ] Использовать CSS-переходы вместо JS-анимаций
[ ] Добавить async/defer к тегам сторонних скриптов
[ ] Оптимизировать порядок выполнения JS для LCP-элемента
**CLS (10 пунктов)**
[ ] Задать ширину/высоту для всех изображений и видео
[ ] Зарезервировать минимальную высоту для рекламных контейнеров
[ ] Размещать динамически вставляемый контент внизу
[ ] Применить font-display: swap к правилам @font-face
[ ] Добавить теги ссылок для предварительной загрузки шрифтов
[ ] Анимировать только transform/opacity (без свойств, меняющих макет)
[ ] Использовать скелетон-загрузчики, чтобы заранее резервировать место под контент
[ ] Проверить, что sticky/fixed-элементы не сдвигают контент
[ ] Сохранять позицию прокрутки при вставке элементов в бесконечной прокрутке
[ ] Исправить высоту анимации переключения вкладок с помощью overflow: hidden
Инструменты измерения
| Инструмент | Назначение | URL |
|---|---|---|
| PageSpeed Insights | Данные реальных пользователей по LCP/INP/CLS | pagespeed.web.dev |
| Lighthouse | Оценка производительности на основе лабораторного тестирования | Chrome DevTools → Lighthouse |
| WebPageTest | Тестирование из разных регионов мира | webpagetest.org |
| Chrome DevTools | Подробное профилирование | F12 → вкладка Performance |
| Core Web Vitals Report | Полевые данные CrUX для SEO | Search Console |
FAQ
**Q1. Насколько Core Web Vitals влияют на позиции в Google?** A. Google описывает CWV как «сигнал для разрешения ничьей» — когда качество контента одинаковое, выигрывает более быстрый сайт. Mobile Page Experience использует CWV как компонент ранжирования. Точный вес не раскрывается, но реальные тесты стабильно показывают различия в позициях между сайтами с LCP > 4s и < 2s.
**Q2. Lighthouse 90+ — это то же самое, что прохождение Core Web Vitals?** A. Нет. Lighthouse использует лабораторную симуляцию; Core Web Vitals опираются на данные реальных пользователей (CrUX / Field Data). Идеальный результат Lighthouse 100 не гарантирует хорошие полевые показатели CWV. Проверьте отчет Core Web Vitals в Google Search Console, чтобы увидеть данные, которые действительно влияют на SEO-ранжирование.
**Q3. Next.js автоматически обеспечивает хорошую производительность?** A. Частично. Next.js из коробки предоставляет оптимизацию изображений (next/image), оптимизацию шрифтов (next/font), разделение кода и SSG/ISR. Однако разработчики должны правильно реализовать атрибуты priority, удалить ненужные сторонние скрипты и указать размеры изображений. При правильной реализации достижим результат Lighthouse 85–95+.
**Q4. Ухудшает ли преобразование в WebP качество изображений?** A. При quality=80–90 разница незаметна для человеческого глаза. WebP обеспечивает файлы на 25–35% меньше по сравнению с JPEG при том же визуальном качестве. AVIF предлагает еще более эффективное сжатие. Такие инструменты, как Squoosh, Cloudinary или next/image, выполняют преобразование автоматически.
**Q5. Как найти элемент, который вызывает CLS?** A. В Chrome DevTools → вкладка Performance после записи ищите маркеры "Layout Shift". PageSpeed Insights также показывает пункт "Avoid large layout shifts" с конкретными элементами, вызывающими смещение. Частые причины: изображения без заданных размеров, загрузка рекламы, которая сдвигает контент, замена шрифтов (FOUT), динамически вставляемый контент.
**Q6. Насколько сторонние скрипты (GA, Hotjar) ухудшают производительность?** A. Существенно — сторонние скрипты могут снизить оценки Lighthouse на 10–20 баллов. GA4 относительно легкий при асинхронной загрузке; тяжелые инструменты вроде Hotjar или Intercom могут заметно ухудшить INP. Используйте next/script со strategy="afterInteractive" или "lazyOnload", чтобы отложить загрузку этих скриптов до момента, когда основная страница станет интерактивной.
**Q7. Mobile LCP всегда медленнее, чем на desktop — как это улучшить?** A. У мобильных устройств медленнее сети и CPU, поэтому улучшать mobile LCP изначально сложнее. Исправления: ① предоставьте уменьшенное hero image через srcset для mobile ② скрывайте несущественные изображения на mobile ③ встраивайте critical CSS inline ④ кэшируйте HTML на CDN edge. Цель: LCP < 2.5s даже на mobile.