Атрибут loading (от английского loading, «загрузка») сообщает браузеру, когда загружать картинку или фрейм: сразу или только когда они приблизятся к экрану. Закрывающей части у атрибута нет, он записывается внутри открывающего тега: loading="lazy". Закрывающий тег нужен самому элементу не всегда: у <img> его нет, а у <iframe> он обязателен.
Значение lazy («ленивый») откладывает загрузку: пока картинка далеко внизу страницы, файл не скачивается. Посетитель, который не дочитал до конца, не тратит на него трафик, а первый экран грузится быстрее. Но у этого есть цена и несколько неочевидных правил: картинке нужны размеры, а загрузка начинается заранее, а не в момент появления.
<img src="cat.jpg" alt="Кот" width="400" height="300"
loading="lazy">
<iframe src="map.html" width="600" height="400"
loading="lazy"></iframe>
В этой статье
- Что такое атрибут loading в HTML и зачем он нужен
- Для каких тегов работает loading: img и iframe
- Какие значения принимает loading: lazy и eager
- Как далеко от экрана браузер начинает загрузку
- Loading и размеры: зачем ленивой картинке width и height
- Какие картинки не делают ленивыми: первый экран и главная картинка
- Скрытые и свёрнутые картинки: display none, details и за краем экрана
- Loading у iframe: ленивые карты и видео
- Loading в JavaScript: свойство loading, new Image() и событие load
- Частые ошибки в атрибуте loading
- Шпаргалка по атрибуту loading
Что такое атрибут loading в HTML и зачем он нужен
Обычно браузер начинает скачивать все картинки сразу, как только найдёт их в разметке, даже если до них нужно прокручивать страницу несколько экранов. Атрибут loading позволяет изменить это: файлы, которые пока никому не нужны, ждут своей очереди.
Это подсказка, а не команда. Браузер сам решает, на каком расстоянии от экрана начать загрузку, и вы это расстояние не задаёте. Размер картинки, как и раньше, задают width и height, а выбор файла среди нескольких вариантов делают srcset и sizes.
loading="lazy": загрузка откладывается, пока элемент далеко от экрана.loading="eager": загрузка идёт сразу. Так работает любой тег, у которого атрибута нет.- Размер файла атрибут не уменьшает: он только выбирает момент, когда файл скачать.
Для каких тегов работает loading: img и iframe
В современном HTML атрибут loading есть у двух тегов. У других тегов, включая <picture> и <source>, его нет: ленивость включают у самого img.
| Тег | Что откладывает loading | Пример записи |
|---|---|---|
<img> | Скачивание файла картинки | <img src="cat.jpg" alt="Кот" width="400" height="300" loading="lazy"> |
<iframe> | Загрузку страницы во фрейме: карты, видео, виджетов | <iframe src="map.html" width="600" height="400" loading="lazy"></iframe> |
Картинки, записанные в CSS как background-image, под атрибут не попадают: у них нет тега, которому его можно записать. Обычное расположение атрибута рядом с src и alt: порядок записи в теге значения не имеет.
Какие значения принимает loading: lazy и eager
По стандарту у атрибута два значения: lazy и eager. Остальные записи браузер не принимает, но страницу не ломает. Он просто ведёт себя так, будто атрибута нет. Результаты замеров в браузере, на котором я проверял.
| Запись | Что показал браузер | Пример записи |
|---|---|---|
lazy | Картинка далеко внизу не загружена | loading="lazy" |
eager | Загружена сразу | loading="eager" |
LAZY, Lazy | Работает как lazy: регистр значения не важен | loading="LAZY" |
auto | Загружена сразу | loading="auto" |
| Пустое значение | Загружена сразу | loading="" |
lazy с пробелом в начале | Загружена сразу: пробел делает значение неверным | loading=" lazy" |
| Любой другой текст | Загружена сразу | loading="garbage" |
Из этого следует практический вывод: если вам кажется, что ленивая загрузка не работает, сначала посмотрите на написание значения. Лишний пробел, кавычка или опечатка тихо отключают её.
Пример: какие значения loading включают ленивую загрузку
В блоке ниже картинка лежит очень далеко внизу. Выберите значение и посмотрите, загрузилась ли она до прокрутки, а затем нажмите кнопку, чтобы проверить загрузку при прокрутке.
Загрузку выполняет ваш браузер, результат может отличаться от моих замеров. Картинка создаётся прямо в демонстрации.
Как далеко от экрана браузер начинает загрузку
«Ленивая» не значит «в момент появления». Браузер начинает загрузку заранее, чтобы картинка успела прийти к моменту, когда посетитель до неё долистает. Расстояние зависит от браузера и скорости сети, поэтому точной цифры нет. Вот что показал замер в браузере, на котором я проверял: окно высотой 600 пикселей, 9 ленивых картинок на разной глубине.
| Расстояние до нижнего края окна | Загружена сразу |
|---|---|
| В окне и до 1400 пикселей | Да |
| 1900 пикселей | Да |
| 2400 пикселей | Да |
| 3400 пикселей | Нет |
| 5400 пикселей | Нет |
Два вывода для практики. Во-первых, на коротких страницах ленивая загрузка почти ничего не даёт: до картинок, которые лежат недалеко внизу, браузер дотянется сам. Во-вторых, проверять ленивую загрузку нужно на длинной странице, иначе кажется, что атрибут не работает.
Пример: как далеко вперёд загружает браузер
В ленте 100 ленивых картинок. Прокручивайте её и следите, сколько картинок ниже экрана уже загружено. Загруженные получают зелёную рамку.
Запас загрузки задаёт ваш браузер, у других он может быть меньше или больше.
Loading и размеры: зачем ленивой картинке width и height
Ленивая картинка без размеров ломает саму идею отложенной загрузки. Пока файл не загружен, у картинки нет высоты, и все такие картинки помещаются в первый экран одновременно. Браузер видит их «рядом» и загружает все. По результатам замеров 30 ленивых картинок без width и height загрузились все до единой, а из 60 ленивых картинок 100 на 100 пикселей с записанными размерами загрузилась 36 из них.
Второй довод про страницу: когда файл придёт, высота картинки изменится, и текст ниже сдвинется. Как этого избежать, рассказано на страницах про width и height. Для ленивой картинки это правило обязательно.
<img src="cat.jpg" alt="Кот"
width="400" height="300"
loading="lazy">
Пример: ленивые картинки без размеров и с размерами
Выберите вариант. Лента из 80 ленивых картинок создаётся заново, после этого считается, сколько из них загружено. Подготовка занимает около секунды.
Результат считает ваш браузер. Без размеров загружаются все картинки, с размерами только те, что ближе к экрану.
Какие картинки не делают ленивыми: первый экран и главная картинка
Ленивую загрузку включают не всем картинкам подряд. Картинка в первом экране загрузится сразу, даже с loading="lazy": при замере она была в окне, и её файл запросился при открытии страницы. Значит, выгоды атрибут не даёт, и в таких случаях его просто не пишут.
Практическое правило такое. Главную картинку страницы, логотип в шапке и всё, что видно без прокрутки, оставляют без loading или записывают loading="eager". Ленивыми делают картинки, до которых посетителю нужно прокручивать: галереи, статьи, длинные ленты.
<img src="hero.jpg" alt="Главная" width="1200" height="600">
<img src="gallery-1.jpg" alt="Фото 1" width="400" height="300"
loading="lazy">
Скрытые и свёрнутые картинки: display none, details и за краем экрана
Ленивая картинка, которой не видно, ведёт себя по-разному в зависимости от способа скрытия. Это важно для каруселей, вкладок и раскрывающихся блоков.
| Как скрыта картинка | С loading="lazy" | Без атрибута |
|---|---|---|
display: none | Не загружена | Загружена |
В закрытом details | Не загружена, загрузилась при открытии | Загружена сразу |
visibility: hidden | Загружена | Загружена |
opacity: 0 | Загружена | Загружена |
| За левым или правым краем окна (минус или плюс 5000 пикселей) | Не загружена | Загружена |
| В прокручиваемом блоке далеко внизу | Не загружена | Загружена |
Выводы для вёрстки. Картинки в закрытых вкладках, слайдах и раскрывающихся блоках с loading="lazy" подгрузятся только при их показе, поэтому на переключении возможна задержка. Скрытие через visibility и opacity загрузку не откладывает: для браузера такие картинки остаются на странице.
Loading у iframe: ленивые карты и видео
У <iframe> атрибут работает так же: фрейм далеко внизу не загружается, пока посетитель не приблизится. Это особенно полезно для карт и встроенных видео: такие фреймы загружают много скриптов и данных. По результатам замеров фрейм в 5000 пикселях ниже окна с loading="lazy" не запросил страницу, пока я не прокрутил к нему, а без атрибута запросил сразу.
<iframe src="https://example.com/map"
width="600" height="400"
loading="lazy" title="Карта"></iframe>
Так же, как и картинке, фрейму нужны width и height: без них область под фрейм по умолчанию получается 300 на 150 пикселей, и расположение страницы после загрузки может измениться. Подробнее о размерах фрейма сказано на страницах про width и height.
Loading в JavaScript: свойство loading, new Image() и событие load
Атрибут доступен из скрипта как свойство loading у картинки и у фрейма. Свойство приводит значение к одному из допустимых.
| Состояние | Значение свойства | Пример записи |
|---|---|---|
| Атрибута нет | "auto" | img.loading |
Атрибут LAZY | "lazy", а сам атрибут остаётся как записан | img.loading = "LAZY" |
| Неверное значение | "auto" | img.loading = "junk" |
| У фрейма без атрибута | "auto" | iframe.loading |
Если создавать картинку скриптом, loading удобно записывать до src. По результатам замеров ленивая картинка, созданная через new Image() с записанным заранее loading, далеко внизу страницы не запросилась, а с loading = "eager" запросилась сразу. Ещё одно свойство ленивой загрузки: она не задерживает событие load окна. Обычная картинка с задержкой в одну секунду отодвинула событие примерно на секунду, а ленивая, ещё не начавшая загрузку, нет.
const img = new Image();
img.loading = 'lazy'; // до src
img.width = 400;
img.height = 300;
img.src = 'cat.jpg';
document.body.append(img);
console.log(img.loading); // "lazy"
Частые ошибки в атрибуте loading
Большинство ошибок связано с тем, что lazy считают универсальным ускорителем и записывают всем картинкам подряд.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
loading="lazy" у главной картинки первого экрана | Выгоды нет: картинка в окне загружается сразу, а запись только усложняет выбор момента | Убрать атрибут или записать eager |
Ленивая картинка без width и height | Высота равна нулю, все картинки оказываются «рядом» и загружаются сразу | Записать оба размера |
loading=" lazy" | Пробел делает значение неверным, загрузка не откладывается | Писать без пробелов: lazy |
loading="true", loading="yes" | Любое значение кроме lazy и eager читается как обычная загрузка | Писать только lazy |
| Ждут загрузки точно в момент появления | Браузер начинает заранее, на запас в сотни пикселей | Не рассчитывать на точный момент |
Ждут, что lazy уменьшит файл | Размер файла не меняется, меняется только момент загрузки | Сжать файл отдельно или дать несколько файлов через srcset |
| Проверяют на короткой странице | Картинки внизу загружены сразу, кажется, что атрибут не работает | Проверять на длинной странице с прокруткой |
| Ленивые картинки в закрытых вкладках и слайдах | Загрузка идёт только при показе, на переключении задержка | Для первого слайда убрать lazy |
loading у source или picture | У этих тегов атрибута нет | Записать у вложенного img |
Ждут, что lazy сработает для фона в CSS | Фон не тег, атрибут к нему не относится | Заменить фон на тег img или грузить фон скриптом |
Ленивый фрейм без width и height | Под фрейм резервируется 300 на 150 пикселей, страница сдвигается | Записать размеры фрейма |
Скрывают ленивую картинку через display: none и ждут загрузки заранее | Картинка не загружается, пока её не покажут | Для скрытия без отсрочки загрузки использовать visibility или opacity |
Шпаргалка по атрибуту loading
Всё главное из статьи в одной таблице.
| Задача | Как записать | Пример записи |
|---|---|---|
| Отложить загрузку картинки | Значение lazy и размеры | <img src="a.jpg" alt="" width="400" height="300" loading="lazy"> |
| Отложить загрузку фрейма | Значение lazy у iframe | <iframe src="map.html" width="600" height="400" loading="lazy"></iframe> |
| Загрузить сразу | Без атрибута или eager | <img src="hero.jpg" alt="" loading="eager"> |
| Главная картинка страницы | Без lazy | <img src="hero.jpg" alt=""> |
| Скрытая картинка | Не display: none, если нужна заранее | img { opacity: 0; } |
| Картинка из скрипта | loading до src | img.loading = 'lazy'; img.src = 'a.jpg'; |
| Прочитать значение | Свойство loading | img.loading |
| Нельзя в loading | Пробелы, true, пустое значение | loading=" lazy" |