Lazy loading — паттерн отложенной загрузки изображений и видео: ресурс грузится только когда пользователь дошёл до него скроллом. Экономит трафик и ускоряет первую отрисовку, особенно на длинных страницах с тяжёлыми картинками.
В современных браузерах поддерживается нативно через атрибут loading="lazy" на тегах img и iframe. Не применять к LCP-картинке: главное изображение должно грузиться сразу, иначе LCP падает.
<img src="hero.jpg" loading="lazy" decoding="async" width="800" height="450"> // Картинка грузится только когда долистали до неё // width/height — обязательны для CLS = 0
<img src="banner.jpg" loading="lazy" width="800" height="400"> — баннер ниже первого экрана загрузится при скролле.
Главная ловушка нативного lazy loading — пометить им изображение, которое и есть LCP-элемент. Браузер откладывает его загрузку, и метрика проседает на 300–800 мс даже на быстром канале. Правило простое: всё, что попадает в первый экран (hero-баннер, первая картинка статьи), грузится обычным образом или через fetchpriority="high", а loading="lazy" вешается только на то, что ниже линии сгиба. Проверить, какой элемент стал LCP, можно во вкладке Performance в DevTools или в отчёте PageSpeed Insights — он подсвечивает конкретный узел.
Второй частый промах — отсутствие width и height у отложенных картинок: пока изображение не подгрузилось, у браузера нет его размеров, контент прыгает и растёт CLS. Поэтому атрибуты размеров (или aspect-ratio в CSS) обязательны для каждого lazy-img. Старые JS-библиотеки вроде lazysizes сегодня избыточны: нативный loading="lazy" поддерживают все актуальные браузеры, а свой скрипт добавляет лишний вес и риск, что картинки не прогрузятся при выключенном JS — Яндекс и Google такие изображения могут не проиндексировать.
Карточки каталога и картинки в подвале статьи грузятся по мере скролла, экономя трафик и время первой отрисовки.
Hero-баннер и LCP-картинку грузим сразу — иначе LCP падает на сотни миллисекунд.
Без width/height или aspect-ratio отложенная картинка двигает контент и портит CLS при подгрузке.
Карточка товара в каталоге: первое фото — , а пять фото в галерее ниже — . На странице с 40 карточками это срезает первоначальную загрузку с 6 МБ до ~0,9 МБ, LCP падает с 3,4 до 1,8 с.
Главная ошибка — отложить загрузку картинки первого экрана. Браузер откладывает её до прокрутки, и метрика отрисовки крупного элемента ухудшается ровно на то время, которое вы сэкономили. Правило такое: всё, что видно без прокрутки, грузится сразу, остальное откладывается.
Вторая ошибка — отложенная загрузка без заданных размеров: место под картинку не зарезервировано, и содержимое прыгает при подгрузке, портя сдвиг раскладки. Поэтому у каждой картинки указывают ширину и высоту. Встроенный в браузеры атрибут покрывает большинство случаев, и подключать для этого отдельную библиотеку обычно не нужно.
Частые вопросы
Какие изображения нельзя откладывать?
Всё, что попадает в первый экран: главную картинку, логотип, фон шапки. Отложенная загрузка такого элемента напрямую ухудшает время отрисовки крупного элемента и портит впечатление от страницы.
Нужна ли отдельная библиотека?
В большинстве случаев нет: браузеры поддерживают отложенную загрузку через атрибут у картинок и встраиваемых блоков. Библиотеку подключают только под нестандартные сценарии вроде фоновых изображений.
Видят ли поисковые системы отложенные картинки?
Обычно да, если используется встроенный механизм браузера и у изображения есть обычный адрес в разметке. Собственные реализации на скриптах, подставляющие адрес позже, робот иногда пропускает.
Почему страница прыгает при прокрутке?
Потому что у изображений не заданы размеры, и место под них не зарезервировано. Укажите ширину и высоту каждой картинке: браузер заранее оставит место, и содержимое перестанет сдвигаться.