Lazy loading (отложенная загрузка) — техника, при которой изображения загружаются только при приближении к области просмотра. Это уменьшает начальный объём данных и ускоряет загрузку страницы. В этой статье — как настроить lazy loading правильно.
Зачем нужен lazy loading
| Преимущество | Описание |
|---|---|
| Быстрая начальная загрузка | Меньше запросов и данных при первом рендере |
| Экономия трафика | Изображения ниже экрана не загружаются, если пользователь не прокрутил |
| Лучший LCP | Ресурсы концентрируются на контенте выше сгиба |
| Меньше нагрузки на сервер | Меньше одновременных запросов |
Для страниц с большим количеством изображений (каталоги, галереи, блоги) эффект особенно заметен.
Нативный lazy loading (loading="lazy")
Современные браузеры поддерживают атрибут loading="lazy" у <img> и <iframe>.
<img src="photo.jpg" alt="Описание" loading="lazy" width="800" height="600">
Как это работает
Браузер откладывает загрузку изображения, пока оно не приблизится к viewport (с запасом, например 1250px). Точное поведение зависит от браузера.
Важно: width и height
Указывайте width и height, чтобы избежать сдвига контента (CLS) при загрузке:
<img src="photo.jpg" alt="Описание" loading="lazy" width="800" height="600">
Без размеров браузер не знает соотношение сторон и при загрузке картинки контент «прыгает».
Поддержка браузеров
Chrome 76+, Firefox 75+, Safari 15.4+, Edge 79+. Для старых браузеров изображение загрузится сразу — деградация безопасна.
Что не ленить
Не используйте loading="lazy" для:
- Изображений выше сгиба (LCP-элемент)
- Логотипа в шапке
- Первого экрана (hero-изображение)
Эти изображения должны загружаться сразу. Для них либо не указывайте loading, либо используйте loading="eager" (значение по умолчанию).
<!-- Hero-изображение — без lazy -->
<img src="hero.jpg" alt="Главный баннер" width="1920" height="1080">
<!-- Контент ниже сгиба — lazy -->
<img src="product-1.jpg" alt="Товар 1" loading="lazy" width="400" height="400">
Lazy loading для iframe
<iframe src="https://example.com/embed" loading="lazy" width="600" height="400"></iframe>
Полезно для встроенных видео, карт и виджетов.
JavaScript: Intersection Observer
Для кастомной логики (например, placeholder, анимация появления) можно использовать Intersection Observer:
const images = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src || img.getAttribute('data-src');
img.removeAttribute('data-src');
observer.unobserve(img);
}
});
});
images.forEach(img => imageObserver.observe(img));
Разметка:
<img data-src="photo.jpg" alt="Описание" width="800" height="600" src="placeholder.jpg">
Для большинства случаев нативного loading="lazy" достаточно. JavaScript нужен при особых требованиях (blur-up, кастомные placeholder).
Lazy loading и SEO
- Контент в изображениях индексируется. Lazy loading не мешает краулерам — Google выполняет прокрутку и загружает отложенные изображения.
- Важно: не скрывайте ключевой контент в изображениях, которые загружаются только при скролле. LCP-элемент не должен быть lazy.
Влияние на Core Web Vitals
| Метрика | Влияние |
|---|---|
| LCP | Положительное — меньше конкуренции за bandwidth при начальной загрузке |
| CLS | Нейтральное при указанных width/height; без них — риск сдвигов |
| FID/INP | Нейтральное или положительное — меньше работы при загрузке |
Проверка: Web Vitals на reChecker.
Частые ошибки
| Ошибка | Решение |
|---|---|
| Lazy для LCP-изображения | Убрать loading="lazy" с hero/первого экрана |
| Нет width/height | Добавить для предотвращения CLS |
| Lazy для всех img подряд | Первые 1–2 изображения оставить без lazy |
| data-src без fallback | При отключённом JS изображение не загрузится — использовать noscript с обычным img |
Чек-лист
| Проверка | Действие |
|---|---|
| LCP-изображение без lazy | Проверить hero, первый экран |
| Остальные изображения с loading="lazy" | Добавить атрибут |
| width и height у всех img | Указать для CLS |
| iframe с отложенной загрузкой | Добавить loading="lazy" |
| Тест в браузере | Проверить, что ниже сгиба загружается при скролле |
Инструменты проверки
- Проверка изображений reChecker — анализ атрибутов, размеров, форматов
- Web Vitals reChecker — LCP, CLS, FID
- Chrome DevTools — Network (throttling), отключение кэша, проверка порядка загрузки
Заключение
Lazy loading ускоряет загрузку страницы и снижает трафик. Используйте нативный loading="lazy" для изображений ниже сгиба, не применяйте его к LCP-элементам и обязательно указывайте width/height. Проверяйте результат через проверку изображений и Web Vitals на reChecker. Дополнительно — оптимизация изображений и WebP/AVIF.
Lazy loading для background-image
CSS background-image не поддерживает loading="lazy". Варианты:
- Использовать img с loading="lazy" и object-fit для визуального эффекта фона
- Загружать background через JavaScript при появлении в viewport (Intersection Observer)
- Для критичного фона — не откладывать загрузку
Lazy loading и печать
При печати страницы отложенные изображения могут не загрузиться. Решение: медиа-запрос @media print с принудительной загрузкой или предупреждение пользователю. Для большинства сайтов это не критично.
Lazy loading в каруселях и слайдерах
В каруселях часто скрыты изображения вне текущего слайда. Рекомендации:
- Загружать только видимое изображение при инициализации
- Подгружать соседние при наведении или за 1 слайд до показа
- Использовать loading="lazy" для изображений в невидимых слайдах (если они в DOM)
Часто задаваемые вопросы
Влияет ли lazy loading на индексацию?
Google выполняет прокрутку и загружает отложенные изображения. Контент индексируется. Не применяйте lazy к LCP-элементу — это может ухудшить метрики.
Нужен ли lazy для изображений выше сгиба?
Нет. Изображения в первом экране должны загружаться сразу. Lazy для них бесполезен и может навредить LCP.
Работает ли loading="lazy" в iframe?
Да. Атрибут loading="lazy" поддерживается для iframe. Полезно для встроенных видео и виджетов.