Поддержка встроенной ленивой загрузки изображений и iframe пришла в веб!
Начиная с Chrome 76 версии, вы можете использовать новый атрибут loading
для ленивой загрузки ресурсов без необходимости писать для этого дополнительный код или использовать стороннюю JavaScript-библиотеку. Давайте рассмотрим детали.
Примечание от переводчика
Большая просьба снисходительно отнестись к замеченным ошибкам в переводе, грамматике или пунктуации, и сообщить о них для исправления.
Спасибо
Это видео демонстрирует пример этой функции:
Почему встроенная ленивая загрузка?
Согласно HTTPArchive, изображения являются наиболее востребованным типом ресурсов на большинстве сайтов и обычно отнимают больше пропускной способности канала, чем любые другие. На 90-м процентиле, сайты отправляют около 4.7 МБ изображений на десктопы и мобильные устройства. Достаточно много фотографий с кошками.
Встроенные iframe также используют много данных и могут вредить производительности страницы. Загрузка некритичных изображений и iframe только в тот момент, когда пользователь может увидеть их, улучшает скорость загрузки страницы, минимизирует нагрузку на пропускную способность канала пользователя и уменьшает использование памяти.
В данный момент существует два способа отложить загрузку изображений и фреймов, расположенных за пределами экрана:
- использование Intersection Observer API
- использование обработчиков событий
scroll
,resize
илиorientationchange
Любой из вариантов может позволить разработчикам включить функционал отложенной загрузки, и многие создали сторонние библиотеки, чтобы предоставить абстракции, которые использовать еще проще. При наличии поддержки ленивой загрузки непосредственно в браузере, не возникнет потребности в сторонней библиотеке. Встроенная ленивая загрузка также гарантирует, что отложенная загрузка изображений и фреймов продолжит работать, даже если JavaScript отключен на стороне клиента.
Атрибут loading
Сегодня Chrome уже загружает изображения с разным приоритетом, в зависимости от того, где они расположены относительно области просмотра устройства. Изображения ниже области просмотра загружаются с меньшим приоритетом, но всё ещё загружаются, как можно быстрее.
В Chrome 76 вы можете использовать атрибут loading
, чтобы окончательно отложить загрузку изображений и фреймов за пределами экрана, до которых можно дойти прокруткой:
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
<iframe src="https://example.com" loading="lazy"></iframe>
Поддерживаемые значения атрибута loading
:
auto
: настройка режима ленивой загрузка, выставленная в браузере по умолчанию. То же, что отсутствие атрибутаlazy
: отсрочка загрузки ресурса до тех пор, пока он не достигнет расчетного расстояния от области просмотраeager
: немедленная загрузка ресурса, несмотря на его расположение на странице
Эта функция продолжит обновляться, пока не будет запущена в стабильной версии (не раньше Chrome 76). Но вы можете опробовать её, активировав следующие флаги в Chrome:
- chrome://flags/#enable-lazy-image-loading
- chrome://flags/#enable-lazy-frame-loading
Порог расстояния загрузки
Все изображения и фреймы, видимые на странице без необходимости прокрутки, загружаются стандартно. Те, которые располагаются ниже области просмотра устройства, загружаются только тогда, когда пользователь прокручивает до них.
Расстояние, при котором начинается загрузка, не фиксировано и изменяется в зависимости от нескольких факторов:
- тип ресурса, который должен быть загружен (изображение или фрейм)
- включен ли "Lite mode" в браузере Chrome для Android
- эффективный тип соединения
Вы можете найти значения по умолчанию для разных типов эффективных соединений в Chromium source. Эти показатели и даже подход загрузки при достижении определенного расстояния от области просмотра, могут меняться в ближайшем будущем, так как команда Chrome улучшает эвристику, чтобы определить, когда начинать загрузку.
В Chrome 77 вы можете экспериментировать с этими различными пороговыми значениями путем замедления скорости соединения в DevTools. Во время этого вам потребуется переопределить эффективный тип соединения в браузере с помощью флага chrome://flags/#force-effective-connection-type.
Загрузка изображений
Атрибут loading влияет на фреймы иначе, чем на изображения, в зависимости от того, является ли фрейм скрытым (скрытые фреймы часто используются для задач аналитики или общения). Chrome использует следующие критерии, чтобы определить, является ли фрейм скрытым:
- ширина и высота фрейма 4px или меньше
- применяются свойства
display: none
илиvisibility: hidden
- фрейм расположен за пределами экрана с помощью отрицательного позиционирования по осям X или Y
Если фрейм соответствует любому из этих условий, Chrome считает его скрытым и не будет загружать в отложенном режиме в большинстве случаев. Фреймы, не являющиеся скрытыми, будут загружены только тогда, когда попадут в пределы порога загрузки. Для фреймов, которые все еще загружаются в режиме отложенной загрузки, отображается плейсхолдер
FAQ
Есть ли планы расширить эту функцию?
Есть планы изменить режим отложенной загрузки браузера по умолчанию, чтобы автоматически отображать в таком режиме любые изображения и фреймы, загрузку которых можно отложить, если включен Lite mode в Chrome для Android.
Можно ли изменить расстояние до изображения или фрейма, при котором запускается отложенная загрузка?
Эти значения жестко закодированы и не могут быть изменены через API. Однако, они могут измениться в будущем, так как команда Chrome экспериментирует с разными пороговыми расстояниями и переменными.
Могут ли изображения, заданные через CSS-свойство background, получить атрибут loading?
Нет, в данный момент он может использоваться только тегами
Как работает атрибут loading с изображениями, которые находятся в области видимости, но не видны (например, карусель)?
В отложенном режиме загружаются только те изображения, которые находятся на определенном расстоянии от нижней грани области просмотра устройства. Все изображения выше области просмотра, независимо от того, видны они в данный момент, загружаются в обычном режиме.
Что, если я уже использую стороннюю библиотеку или скрипт для отложенной загрузки изображений или фреймов?
Атрибут loading не должен влиять на код, который в отложенном режиме загружает данные, но важно учитывать некоторые важные моменты:
- Если ваш сторонний загрузчик в отложенном режиме пытается загрузить изображения или фреймы раньше, чем их будет загружать Chrome в обычном режиме, то есть, на расстоянии, превышающем порог расстояния загрузки браузером, они все еще будут отложены и загружены по правилам обычного поведения браузера
- Если ваш сторонний загрузчик использует более короткое расстояние, чтобы определить, когда загружать конкретное изображение или фрейм, чем браузер, то поведение будет соответствовать настройкам вашего загрузчика
Одна из важных причин продолжить использовать стороннюю библиотеку параллельно с loading=«lazy» заключается в предоставлении полифила для браузеров, не поддерживающих данный атрибут.
Другие браузеры поддерживают встроенную отложенную загрузку?
Атрибут loading
можно рассматривать, как прогрессивное улучшение. Браузеры, которые поддерживают его, могут загружать изображения и фреймы в отложенном режиме. Те, что не поддерживают — пока что загружают изображения как обычно. С точки зрения кроссбраузерной поддержки, атрибут loading
поддерживается в Chrome 76 и любых браузерах, основанных на базе Chromium 76. Также существует открытый баг про реализацию данной функции в Firefox.
Похожее API было предложено и использовалось в IE и Edge, но оно было сфокусировано на понижении приоритетов загрузки вместо полного её откладывания.
Как поступить с браузерами, которые еще не поддерживают встроенную отложенную загрузку?
Создайте полифил или используйте стороннюю библиотеку, чтобы загружать изображения на сайте в отложенном режиме. Свойство loading может быть использовано для определения, поддерживается ли функционал в браузере:
if ('loading' in HTMLImageElement.prototype) {
// supported in browser
} else {
// fetch polyfill/third-party library
}
Например, lazysizes — популярная JavaScript библиотека для ленивой загрузки. Вы можете определить поддержку атрибута loading
, чтобы загрузить эту библиотеку только, когда loading
не поддерживается. Это работает следующим образом
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">
<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach(img => {
img.src = img.dataset.src;
});
} else {
// Dynamically import the LazySizes library
const script = document.createElement('script');
script.src =
'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/4.1.8/lazysizes.min.js';
document.body.appendChild(script);
}
</script>
Демонстрация работы. Испробуйте это в таким браузерах, как Firefox или Safari, чтобы увидеть фолбек в действии.
Библиотека lazysizes также обеспечивает плагин встроенной загрузки, который использует встроенную отложенную загрузку, когда это возможно, и задействует функционал библиотеки, когда в этом есть потребность.
Как отложенная встроенная загрузка влияет на рекламу на странице?
Вся реклама, представленная в виде изображений или фреймов, также загружается в отложенном режиме, как любые другие изображения или фреймы.
Как изображения обрабатываются, если веб-страницу распечатать?
Хотя функционала нет в Chrome 76, существует открытая проблема, обеспечивающая немедленную загрузку всех изображений и фреймов при печати страницы.
Заключение
Использование встроенной поддержки ленивой загрузки изображений и фреймов может существенно облегчить повышение производительности веб-страниц.
Если замечаете любое необычное поведение при включении этой функции в Chrome, сообщите об ошибке.
Автор: Рома