Как работает lazy loading
Классическая реализация через Intersection Observer:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // заменяем заглушку на реальный URL
observer.unobserve(img); // наблюдение больше не нужно
}
});
}, { rootMargin: '200px' }); // начинаем грузить за 200px до появления
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));
rootMargin: '200px' — запас: изображение начинает загружаться, когда до него остаётся 200 пикселей прокрутки. Это убирает видимую задержку при быстрой прокрутке.
Для нативного варианта — просто атрибут в HTML:
<img src="product.jpg" loading="lazy" alt="Описание товара" width="300" height="300" />
Ширина и высота обязательны — без них браузер не резервирует место и возникает CLS (Cumulative Layout Shift).
Что выигрывает от lazy loading в e-commerce
Страницы каталога (PLP). Сотни карточек товаров с изображениями — без lazy loading браузер загрузит их все при открытии страницы. С lazy loading — только видимые. Экономия трафика: 60–90% для типичного листинга из 48–96 товаров.
Рекомендательные виджеты. Блоки «Похожие товары», «С этим покупают» в нижней части карточки товара или на странице корзины — типичные кандидаты на lazy loading. Виджет запрашивает рекомендации у API только при попадании в viewport.
Изображения в блоге. Статьи с иллюстрациями внутри длинного текста — все изображения ниже первого экрана делают lazy.
Как не навредить Core Web Vitals
| Элемент | Рекомендация |
|---|---|
| Hero-изображение, логотип | loading="eager" (по умолчанию) |
| Первые 3–4 карточки товаров | loading="eager" |
| Остальные карточки в листинге | loading="lazy" |
| Виджеты рекомендаций | Lazy loading через Intersection Observer |
| Сниппеты аналитики | async или defer |
Важно: задайте явные
widthиheightдля всех lazy-изображений. Без них браузер не резервирует пространство, что вызывает прыжки контента при прокрутке (CLS > 0.1 — провал в Core Web Vitals).