Я Максим, веб-разработчик. Lazy loading — одна из тех оптимизаций, которые дают максимальный результат при минимальных усилиях. Добавляете один атрибут к изображениям — и страница начинает грузиться заметно быстрее. Но за этой простотой скрываются нюансы, которые влияют на SEO, конверсию и пользовательский опыт. Давайте разберём тему глубже, чем «добавьте loading=lazy и забудьте».
Что такое lazy loading и зачем он нужен
Ленивая загрузка — это подход, при котором изображения загружаются не все сразу при открытии страницы, а по мере того, как пользователь скроллит к ним. Картинка, которая находится за пределами видимого экрана, не скачивается, пока пользователь до неё не доскроллит.
Зачем это нужно? Давайте посчитаем. Типичная страница каталога интернет-магазина содержит 30–50 карточек товаров, и у каждой — хотя бы одно изображение. Средний вес изображения товара — 100–300 КБ. Итого: 30 картинок по 200 КБ — это 6 МБ данных. Плюс баннеры, иконки, декоративные элементы — легко набирается 10 МБ и больше.
Если загружать всё это одновременно, браузер тратит ресурсы на скачивание картинок, которые пользователь, возможно, никогда не увидит. Он пришёл за первыми тремя товарами на экране — а сайт честно скачивает все пятьдесят. Результат: медленная загрузка, высокий показатель отказов, плохие оценки Core Web Vitals.
С lazy loading начальная загрузка сокращается в несколько раз. Браузер скачивает только те изображения, которые видны на первом экране, а остальные подгружает по мере прокрутки. Пользователь получает быструю, отзывчивую страницу.
Как lazy loading влияет на метрики и SEO
Влияние lazy loading на позиции в Яндексе и поведенческие факторы — тема, которую часто недооценивают.
Core Web Vitals
Lazy loading напрямую улучшает несколько ключевых метрик. LCP (Largest Contentful Paint) — крупнейшая отрисовка контента — улучшается, потому что браузер не конкурирует за полосу пропускания с десятками изображений. Главный баннер или основная картинка загружаются быстрее, когда остальные не стоят в очереди.
FID и INP — отзывчивость интерфейса. Когда браузер скачивает 50 изображений одновременно, основной поток перегружен, и интерфейс может подвисать. С lazy loading нагрузка распределяется во времени, страница остаётся отзывчивой.
CLS (Cumulative Layout Shift) — визуальная стабильность. Здесь lazy loading может как помочь, так и навредить. Если изображениям не заданы ширина и высота, при подгрузке они «вталкивают» контент, вызывая сдвиги макета. Об этом поговорим отдельно.
Поведенческие факторы
Быстрая загрузка страницы снижает показатель отказов. По данным многочисленных исследований, каждая секунда задержки загрузки увеличивает процент отказов на 7–10 процентов. Для интернет-магазина с тысячей посетителей в день это десятки потерянных потенциальных клиентов.
Яндекс явно учитывает скорость загрузки как фактор ранжирования. Быстрые страницы получают преимущество в выдаче, а после обновлений алгоритмов Яндекса эта тенденция только усиливается.
Нативный lazy loading: самый простой способ
Современные браузеры поддерживают ленивую загрузку прямо из коробки. Достаточно добавить атрибут к тегу img:
<img src="product.jpg" alt="Красные кроссовки Nike Air Max" loading="lazy" width="400" height="300">Один атрибут — и браузер сам решает, когда загружать изображение. Никакого JavaScript, никаких библиотек, никаких зависимостей. Работает в Chrome, Firefox, Edge, Safari и во всех мобильных браузерах.
Обратите внимание: я указал width и height. Это критически важно. Когда браузер знает размеры изображения до его загрузки, он резервирует место в макете. Без размеров при подгрузке картинки контент «прыгает» — это ухудшает CLS и раздражает пользователей.
Когда НЕ ставить loading="lazy"
Есть изображения, которые обязательно должны загружаться сразу, без задержки.
Hero-баннер — главное изображение первого экрана. Именно оно определяет LCP. Если навесить на него lazy loading, браузер отложит загрузку — и метрика LCP резко ухудшится. Яндекс это заметит.
Логотип компании — маленький файл, который должен быть виден с первого мгновения.
Первые три-четыре карточки каталога — те, что попадают на экран без прокрутки. Их тоже не стоит откладывать.
Правило: всё, что пользователь видит сразу при открытии страницы, — загружается без lazy loading. Всё, что ниже первого экрана, — с lazy loading.
В Next.js для этого используется свойство priority компонента Image:
<Image src="/hero.jpg" alt="Главный баннер" priority width={1200} height={600} />Intersection Observer API: продвинутый подход
Для ситуаций, где нативного lazy loading недостаточно, используется JavaScript API — Intersection Observer. Он отслеживает момент, когда элемент попадает в видимую область экрана, и позволяет запустить любую логику в этот момент.
Зачем нужен Intersection Observer, если есть нативный lazy loading? Несколько причин.
Фоновые изображения. Атрибут loading="lazy" работает только для тегов img и iframe. Фоновые изображения, заданные через CSS background-image, нативный lazy loading не затрагивает. А они бывают тяжёлыми — декоративные блоки, параллакс-секции, полноэкранные фоны.
Видео и iframe. YouTube-видео, встраиваемые карты — каждый такой элемент тянет сотни килобайт скриптов. Загрузка iframe с YouTube до того, как пользователь доскроллит до видео, — пустая трата ресурсов.
Тонкая настройка момента загрузки. Intersection Observer позволяет начать загрузку, когда элемент ещё не видим, но уже близко к зоне видимости. Параметр rootMargin задаёт отступ — например, «начать загрузку, когда до изображения осталось 200 пикселей». Пользователь доскроллит — а картинка уже подгружена. Ощущение мгновенной загрузки.
Анимации при появлении. Кроме загрузки изображений, Intersection Observer используется для запуска анимаций при скролле — плавное появление блоков, fade-in эффекты. Всё это улучшает восприятие скорости.
Lazy loading для разных типов контента
Изображения товаров в каталоге
Самый частый сценарий. Каталог с десятками и сотнями товаров — идеальный кандидат для lazy loading. Каждой карточке — loading="lazy" плюс обязательно width и height (или CSS aspect-ratio). Первые карточки, которые видны без прокрутки, — без lazy loading.
Галерея на странице товара
Многие интернет-магазины показывают 5–10 фотографий товара в слайдере. Первое изображение — без lazy loading, остальные — с lazy loading. Пользователь переключает слайды — изображения подгружаются.
Отзывы с фотографиями
Блок отзывов внизу страницы — часто самый тяжёлый элемент. Фотографии клиентов, скриншоты — всё это весит немало. Lazy loading здесь даёт серьёзный выигрыш, потому что большинство пользователей до отзывов не доскролливает.
Блог и статьи
Длинные статьи с иллюстрациями — ещё один очевидный кандидат. Изображение в середине статьи на 3 000 слов нет смысла загружать, пока читатель на первом абзаце.
Встроенные карты и видео
Виджет Яндекс Карт или YouTube-видео в секции «Контакты» внизу страницы. Без lazy loading они начинают загружать скрипты и данные сразу, утяжеляя страницу. С ленивой загрузкой — только когда пользователь доскроллит.
Плейсхолдеры: что показывать вместо изображения
Пока изображение не загружено, пользователь видит пустое место — или плейсхолдер. Качество плейсхолдера влияет на восприятие скорости.
Самый простой вариант — серый прямоугольник с размерами будущего изображения. Занимает место, предотвращает сдвиг макета, но выглядит скучно.
Skeleton-экран — анимированный серый блок с пульсацией. Создаёт ощущение, что контент «вот-вот загрузится». Широко используется в мобильных приложениях и современных веб-приложениях.
BlurHash — размытый превью-образ изображения размером в десятки байт. Загружается мгновенно, даёт представление о содержимом картинки и плавно заменяется полным изображением. Next.js поддерживает blurDataURL из коробки. Визуально — самый приятный вариант.
Доминантный цвет — фон плейсхолдера окрашивается в основной цвет будущего изображения. Просто, легковесно, выглядит опрятно.
Типичные ошибки при внедрении
За годы работы с оптимизацией сайтов я собрал коллекцию типичных промахов, связанных с lazy loading.
Lazy loading на LCP-элементе. Ставят loading="lazy" на главный баннер — и удивляются, почему LCP ухудшился. Браузер откладывает загрузку самого важного элемента — это прямой вред.
Отсутствие размеров у изображений. Без width и height (или CSS aspect-ratio) браузер не знает, сколько места зарезервировать. При загрузке изображения страница «прыгает» — CLS растёт. Яндекс и Google это фиксируют.
Слишком поздняя подгрузка. Если изображение начинает загружаться только когда оно полностью в зоне видимости — пользователь видит пустой блок на долю секунды. Используйте rootMargin в Intersection Observer, чтобы начинать загрузку заранее, за 100–300 пикселей до зоны видимости.
Lazy loading для критических элементов интерфейса. Иконки навигации, логотип, элементы шапки — они маленькие и должны грузиться мгновенно. Не увлекайтесь, не ставьте lazy loading на всё подряд.
Отсутствие fallback для старых браузеров. Нативный loading="lazy" поддерживается практически везде, но если ваша аудитория использует очень старые устройства — стоит добавить полифилл через Intersection Observer.
Lazy loading в связке с другими оптимизациями
Lazy loading — не единственный инструмент ускорения. Максимальный эффект достигается в связке с другими техниками.
Формат WebP и AVIF. Современные форматы сжатия уменьшают вес изображений на 30–50 процентов по сравнению с JPEG и PNG. В Next.js конвертация происходит автоматически через компонент Image.
Responsive images. Отдавайте разные размеры изображений для разных экранов. Зачем загружать картинку 1200 пикселей на мобильном экране шириной 375 пикселей? Атрибут srcset решает эту задачу.
CDN для статики. Размещение изображений на CDN приближает файлы к пользователю географически — загрузка ускоряется за счёт меньшей задержки.
Preload для LCP-изображения. Те изображения, которые мы исключили из lazy loading (hero-баннер), стоит подключить через link rel="preload" в head — чтобы браузер начал их загрузку ещё раньше.
Каждая из этих оптимизаций добавляет к скорости загрузки. Вместе они превращают тяжёлую страницу в быструю и отзывчивую.
Как проверить, что lazy loading работает правильно
После внедрения обязательно проверьте результат.
Chrome DevTools, вкладка Network — отфильтруйте по типу Img. При загрузке страницы должны скачиваться только изображения первого экрана. Прокрутите вниз — в списке появятся новые запросы. Если все изображения скачались сразу — lazy loading не работает.
Lighthouse-аудит — запустите из DevTools. Lighthouse подскажет, если на LCP-элементе стоит lazy loading или если есть изображения без размеров.
PageSpeed Insights — проверяет реальные данные из Chrome User Experience Report. Здесь видно, как ваши метрики воспринимаются Яндексом и Google.
Яндекс Вебмастер — раздел «Диагностика сайта» показывает проблемы с Core Web Vitals для страниц вашего сайта.
Итог
Lazy loading — обязательная оптимизация для любого сайта с изображениями. Для большинства случаев достаточно нативного атрибута loading="lazy". Для более сложных сценариев — Intersection Observer. Главное — не ставить ленивую загрузку на контент первого экрана, указывать размеры изображений и использовать качественные плейсхолдеры.
Если нужна комплексная оптимизация скорости вашего сайта — обращайтесь, проведу аудит и внедрю все необходимые улучшения.