Ленивая загрузка

Оригинальное название: lazy loading

Коротко

Приём, при котором картинки, видео, фреймы или код загружаются не сразу, а когда приближаются к видимой части экрана или действительно понадобятся.

Что такое «Ленивая загрузка»

Длинная страница каталога может содержать сотню фотографий, а человек часто не долистывает и до середины. Если браузер скачивает всё сразу, первый экран появляется позже, мобильный трафик расходуется впустую, а сервер отдаёт лишние мегабайты. Ленивая загрузка откладывает то, что пока не видно, и освобождает канал для действительно нужного.

Раньше приём делали только скриптами: в разметке вместо src писали data-src, а скрипт подменял атрибут при прокрутке. Сейчас для картинок и фреймов достаточно атрибута, который понимают все современные браузеры.

Встроенный способ

<img src="sofa.webp" width="600" height="400"
     loading="lazy" alt="Диван угловой">
<iframe src="https://example.ru/map" loading="lazy"
        title="Схема проезда"></iframe>

Браузер сам решает, на каком расстоянии от области просмотра начинать загрузку, с учётом скорости соединения. Размеры width и height обязательны: без них место под картинку не зарезервировано, и при появлении она сдвинет текст.

WordPress с версии 5.5 сам добавляет loading="lazy" изображениям в записях, а в более новых версиях старается не ставить его первому крупному изображению страницы.

Когда лениво грузить нельзя

Главная ошибка — отложить картинку первого экрана: баннер, фото товара в карточке, обложку статьи. Браузер узнаёт о ней позже, и метрика LCP из Core Web Vitals ухудшается. Для такого изображения ставят обычную загрузку, а иногда и повышенный приоритет атрибутом fetchpriority="high". Ещё одна ошибка — подгружать контент только по клику или по событию прокрутки: поисковый робот не прокручивает страницу и может не увидеть такие блоки.

Свой вариант для нестандартных случаев

Фоновые картинки в CSS, виджеты чатов, тяжёлые карты и скрипты атрибут не поддерживают. Для них используют наблюдатель пересечений:

const io = new IntersectionObserver((entries) => {
  entries.forEach((e) => {
    if (!e.isIntersecting) return;
    import('./reviews-widget.js').then((m) => m.init(e.target));
    io.unobserve(e.target);
  });
}, { rootMargin: '300px' });
io.observe(document.querySelector('#reviews'));

Модуль отзывов скачается, когда блок окажется в трёхстах пикселях от экрана. Динамический import() здесь — ленивая загрузка кода: скрипт не попадает в основной файл и не тормозит первую отрисовку. Ленивая загрузка обычно входит в первые шаги при ускорении сайта, наряду со сжатием и правильными форматами изображений.

Обновлено:

Все термины раздела «Frontend»

Что будем искать? Например,Продвижение