Рабочие примеры
Тема про производительность — результат часто не визуальный. Поэтому: где есть движение, смотри превью; где приём про загрузку — смотри код и схему «эффекта».
1. Дёшево vs дорого: анимируем transform, а не top
Оба блока двигаются вверх при наведении. Слева — через transform (composite, GPU, без reflow), справа — через top (reflow на каждом кадре). Визуально похоже, по нагрузке — нет. Наведи мышь.
дёшево — только composite
дорого — reflow на каждом кадре
/* ✅ дёшево: GPU, без пересчёта раскладки */
.card:hover { transform: translateY(-8px); }
/* ⚠️ дорого: каждый кадр запускает reflow */
.card-bad:hover { top: -8px; }
2. Ленивая загрузка изображений (loading="lazy")
Атрибут loading="lazy" откладывает загрузку картинок ниже первого экрана до момента, когда пользователь до них доскроллит. Эффект невидим глазу, но первый экран грузится быстрее. Обязательно указывай width и height — это резервирует место и убирает скачок вёрстки (CLS).
<!-- картинка первого экрана: грузим сразу -->
<img src="hero.webp" width="1200" height="600" alt="...">
<!-- картинки ниже: откладываем -->
<img src="gallery-1.webp" width="600" height="400"
loading="lazy" alt="...">
3. Современные форматы изображений (WebP/AVIF)
Один и тот же снимок в WebP/AVIF весит в разы меньше, чем JPEG/PNG при том же качестве (связь с уроком 36). Тег <picture> отдаёт лучший формат, который поддерживает браузер, с откатом на старый. Результат тот же для глаза — но меньше байтов по сети.
<picture>
<source srcset="photo.avif" type="image/avif">
<source srcset="photo.webp" type="image/webp">
<img src="photo.jpg" width="600" height="400" alt="...">
</picture>
4. font-display: swap — текст виден сразу
По умолчанию браузер прячет текст, пока грузится кастомный шрифт («невидимый текст», FOIT). font-display: swap сразу показывает текст системным шрифтом, а потом подменяет на нужный. Контент читаем мгновенно.
@font-face {
font-family: "Inter";
src: url("inter.woff2") format("woff2");
font-display: swap; /* текст виден сразу */
}
5. Critical CSS + минификация
Минифицированный CSS — тот же код без пробелов и переносов: для браузера одинаков, но весит меньше. Critical CSS первого экрана встраивают прямо в <head>, остальное грузят отдельным файлом. Так первый экран рисуется, не дожидаясь всей таблицы стилей.
<head>
<!-- критический CSS первого экрана — инлайн -->
<style>.hero{padding:2rem}.card{gap:1rem}</style>
<!-- остальное грузим отдельно и не блокируем рендер -->
<link rel="stylesheet" href="style.min.css">
</head>