Производительность сайта

Скорость для пользователей и метрик: Core Web Vitals, LCP и CLS, вес страницы, критический CSS, кэш, preload и измерение в Lighthouse.

Уровень: средний 13 разделов 2,5 часа

1. Зачем оптимизировать скорость

Медленный сайт теряет пользователей: половина посетителей уходит, если страница грузится дольше нескольких секунд, а конверсия падает с ростом времени загрузки. Скорость — это бизнес-метрика, и её измеряют не «в секундах», а по сценариям реальных пользователей.

Оптимизация — это не «поставить сжать всё», а расстановка приоритетов: снизить вес самых дорогих ресурсов, ускорить первый показ и убрать прыжки макета. Правило честное: любой атрибут, который ускоряет реального пользователя, побеждает.

2. Core Web Vitals

Google измеряет скорость тремя метриками Core Web Vitals, которые отражают реальный опыт: быстро ли загрузилось главное (LCP), не прыгает ли макет (CLS), и живо ли сайт реагирует (INP). Все три имеют «зелёную зону» — ориентиры для работы.

МетрикаЧто измеряетХорошо
LCP (Largest Contentful Paint)время появления самого крупного контента на экранедо 2,5 с
CLS (Cumulative Layout Shift)насколько макет сдвигается при загрузкедо 0,1
INP (Interaction to Next Paint)задержка реакции на взаимодействиедо 200 мс

LCP обычно определяется картинкой или текстом на первом экране; CLS — «прыжками» блока, когда дозагружается контент (без зарезервированного места); INP — блокирующим JS и тяжёлыми обработчиками.

3. LCP: ускорьте главный экран

Первый экран на десктопе — это hero-картинка и заголовок, на мобильном чаще текст. Ускорение LCP — это сокращение цепочки: DNS → сеть → сервер → CSS → ресурс → отрисовка. Устраняйте самое длинное звено.

<!-- LCP-картинка: качаем сразу и с приоритетом -->
<img src="hero.jpg" width="1200" height="600"
     alt="Баннер" fetchpriority="high">

<!-- подсказываем браузеру критические ресурсы -->
<link rel="preload" href="fonts/hero.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preconnect" href="https://cdn.site.com">
fetchpriority="high" ставьте только на один-два действительно главных ресурса: N картинок с high начнут бороться за очередь и LCP пострадает.

4. CLS: без прыжков

Прыжки макета — когда блок сдвигается после отрисовки. Причины: картинки и видео без размеров, шрифты, подменяющие текст (swap), динамически вставленный контент, баннеры. Лечится резервированием места и запретом внезапных сдвигов.

/* место под картинку/видео */
img, video { aspect-ratio: 4 / 3; object-fit: cover; }

/* шрифт не переставляет текст: предзагрузка + системный запас */
@font-face { font-family: "Inter"; font-display: swap; }
body { font-family: "Inter", system-ui, sans-serif; }

/* динамике не сдвигать страницу внезапно: контейнер с высотой или overflow */
.ad-slot { min-height: 250px; }

5. INP: отклик интерфейса

Реакцию измеряют от действия пользователя до обновления экрана. Долгие главные потоки — синхронный JS, тяжёлые раскладки, крупные DOM-операции — держат интерфейс «замерзшим». INP хорош, когда код выполняет работу быстро и кусочками.

// долгие задачи дробим, чтобы поток дышал
const items = await fetch("/api/items").then(r => r.json());

for (const chunk of chunks(items, 50)) {
  render(chunk);            // рендер частями
  await new Promise(r => setTimeout(r)); // отдаём поток браузеру
}

// лёгкие варианты: requestAnimationFrame для плавных черновиков
INP заменил FID (First Input Delay). Отличие: FID мерял первую задержку, INP — худшее взаимодействие за сессию, поэтому «пики» лоаутов важны, а не только первый клик.

6. Вес страницы и передача

Трафик стоит денег и времени: каждый байт, прошедший по сети, оплачен лимитом и задержкой. Вес страницы считают как сумму всех ресурсов: HTML, CSS, JS, картинки, шрифты. Современные сайты весят 1.5–3 МБ, из которых половина — изображения.

# реальный вес страницы
curl -I https://site.com          # заголовки ресурса
curl -so /dev/null -w "%{size_download}" https://site.com

# в DevTools: Network → размер «Передано» vs «Ресурс»
# передано меньше, если включено сжатие (Content-Encoding)
ПриёмЭкономия
сжатие HTML/CSS/JS (gzip/brotli)до 70–80% передачи
картинки в AVIF/WebP, правильно обрезанныедесятки–сотни КБ
критический CSS инлайн, остальной — отложенноважное быстрее
шрифт одним файлом начертания (не 5)сотни КБ
SVG вместо PNG для иконокбайты вместо КБ
Хорошая привычка после вёрстки: открыть Network, посмотреть «Передано» по крупным ресурсам и спросить «за что именно платит пользователь?». Дальше — резать самый дорогой пункт.

7. Критический CSS

Браузер не рисует страницу, пока не получит весь блокирующий CSS. Если стилей сайта много (500 КБ), первый экран ждёт лишние секунды. Критический CSS — узкий набор правил для первого экрана (тут же, в head), остальное — отдельный файл с отложившимся соединением.

<head>
  <style>
    /* критический CSS: только то, что видно на первом экране */
    body { margin: 0; font: 1rem/1.5 system-ui, sans-serif; }
    .hero { padding: 24px; background: #0f172a; color: #fff; }
  </style>
  <link rel="stylesheet" href="style.css" media="print"
        onload="this.media='all'">
</head>

<noscript><link rel="stylesheet" href="style.css"></noscript>