* РБК — новости

* *

Ленивая загрузка изображений и видео

  1. Что такое ленивая загрузка?
  2. Зачем лениво загружать изображения или видео, а не просто загружать их?
  3. Ленивая загрузка изображений
  4. Встроенные изображения
  5. Использование пересечения наблюдателя
  6. Использование обработчиков событий (наиболее совместимый способ)
  7. Изображения в CSS
  8. Ленивая загрузка видео
  9. Для видео, которое не воспроизводится автоматически
  10. Для видео, выступающего в качестве замены анимированного GIF
  11. Ленивая загрузка библиотек
  12. Что может пойти не так
  13. Следи за сгибом
  14. Сдвиг макетов и заполнителей
  15. Задержка декодирования изображения
  16. Когда вещи не загружаются
  17. Доступность JavaScript
  18. Заключение

Часть изображений а также видео в типичную полезную нагрузку веб-сайта может быть значительным. К сожалению, заинтересованные стороны проекта могут не захотеть вырезать какие-либо медиа-ресурсы из своих существующих приложений. Такие тупики расстраивают, особенно когда все вовлеченные стороны хотят улучшить производительность сайта, но не могут договориться о том, как туда добраться. К счастью, отложенная загрузка - это решение, которое снижает начальную загрузку страницы и время загрузки, но не экономит на контенте.

Что такое ленивая загрузка?

Ленивая загрузка - это метод, который откладывает загрузку некритических ресурсов во время загрузки страницы. Вместо этого эти некритические ресурсы загружаются в момент необходимости. Что касается изображений, то «некритические» часто являются синонимами «за кадром». Если вы использовали Lighthouse и изучили некоторые возможности для улучшения, вы, возможно, видели некоторые рекомендации в этой области в форме Аудит закадровых изображений :

Рисунок 1 Одной из проверок производительности Lighthouse является выявление закадровых изображений, которые являются кандидатами на ленивую загрузку.

Вы, наверное, уже видели ленивую загрузку в действии, и она выглядит примерно так:

  • Вы попадаете на страницу и начинаете прокручивать, когда читаете контент.
  • В какой-то момент вы прокручиваете изображение-заполнитель в окне просмотра.
  • Изображение заполнителя внезапно заменяется окончательным изображением.

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

Рисунок 2 Пример ленивой загрузки изображения в действии. Изображение заполнителя загружается при загрузке страницы (слева), а при прокрутке в область просмотра окончательное изображение загружается в момент необходимости.

Если вы не знакомы с ленивой загрузкой, возможно, вас интересует, насколько полезна техника и в чем ее преимущества. Читай дальше что бы узнать!

Зачем лениво загружать изображения или видео, а не просто загружать их?

Возможно, вы загружаете вещи, которые пользователь может никогда не увидеть. Это проблематично по нескольким причинам:

  • Это пустая трата данных. На неизмеренных соединениях это не самое худшее, что может произойти (хотя вы можете использовать эту драгоценную пропускную способность для загрузки других ресурсов, которые действительно будут видны пользователю). Однако на ограниченных тарифных планах загрузка материалов, которые пользователь никогда не видит, может стать пустой тратой их денег.
  • Это тратит впустую время обработки, батарею и другие системные ресурсы. После загрузки медиа-ресурса браузер должен декодировать его и отобразить его содержимое в окне просмотра.

Когда мы лениво загружаем изображения и видео, мы уменьшаем начальное время загрузки страницы, начальный вес страницы и использование системных ресурсов, что положительно влияет на производительность. В этом руководстве мы расскажем о некоторых методах и предложим рекомендации по отложенной загрузке изображений и видео, а также краткий список некоторых часто используемых библиотек ,

Ленивая загрузка изображений

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

Встроенные изображения

Наиболее распространенными кандидатами на ленивую загрузку являются изображения, используемые в элементах <img>. Когда мы лениво загружаем элементы <img>, мы используем JavaScript, чтобы проверить, находятся ли они в области просмотра. Если они есть, их атрибуты src (а иногда и srcset) заполняются URL-адресами нужного содержимого изображения.

Использование пересечения наблюдателя

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

Обозреватель пересечений проще в использовании и чтении, чем код, использующий различные обработчики событий, поскольку разработчикам нужно всего лишь зарегистрировать наблюдателя, чтобы наблюдать за элементами, а не писать утомительный код обнаружения видимости элементов. Все, что остается сделать разработчику, - это решить, что делать, когда элемент виден. Давайте предположим, что это базовый шаблон разметки для наших лениво загруженных элементов <img>:

<img class = "lazy" src = "placeholder-image.jpg" src = "image-to-lazy-load-1x.jpg" data-srcset = "image-to-lazy-load-2x.jpg 2x, изображение -to-lazy-load-1x.jpg 1x "alt =" Я изображение! ">

Есть три важных элемента этой разметки, на которых мы должны сосредоточиться:

  1. Атрибут class, с помощью которого мы выберем элемент в JavaScript.
  2. Атрибут src, который ссылается на изображение-заполнитель, которое появится при первой загрузке страницы.
  3. Атрибуты data-src и data-srcset, которые являются атрибутами-заполнителями, содержащими URL-адрес изображения, которое мы будем загружать, когда элемент находится в области просмотра.

Теперь давайте посмотрим, как мы можем использовать наблюдатель пересечения в JavaScript для отложенной загрузки изображений с помощью этого шаблона разметки:

document.addEventListener ("DOMContentLoaded", function () {var lazyImages = [] .slice.call (document.querySelectorAll ("img.lazy")); if ("IntersectionObserver" в окне) {let lazyImageObserver = новая функция IntersectionObserver ( (записи, наблюдатель) {records.forEach (function (entry) {if (entry.isIntersecting) {let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; lazyImage.srcset = lazyImage.dataset.srcset; lazyImage .classList.remove ("lazy"); lazyImageObserver.unobserve (lazyImage);}});}); lazyImages.forEach (function (lazyImage) {lazyImageObserver.observe (lazyImage);});} else {// Возможно падение вернуться к более совместимому методу здесь}});

В событии DOMContentLoaded документа этот скрипт запрашивает DOM для всех элементов <img> с классом lazy. Если наблюдатель пересечения доступен, мы создаем новый наблюдатель, который выполняет обратный вызов, когда элементы img.lazy входят в область просмотра. Проверять, выписываться этот пример CodePen чтобы увидеть этот код в действии.

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

Использование обработчиков событий (наиболее совместимый способ)

Хотя для отложенной загрузки следует использовать средство наблюдения за пересечением, требования вашего приложения могут быть такими, чтобы совместимость браузера была критической. Вы можете получить поддержку наблюдателя пересечения polyfill (и это будет проще всего), но вы также можете вернуться к коду, используя свиток , изменить размер и, возможно, orientationchange обработчики событий совместно с getBoundingClientRect чтобы определить, находится ли элемент в окне просмотра.

Предполагая тот же шаблон разметки, что и раньше, следующий JavaScript обеспечивает функцию отложенной загрузки:

document.addEventListener ("DOMContentLoaded", function () {let lazyImages = [] .slice.call (document.querySelectorAll ("img.lazy")); let active = false; const lazyLoad = function () {if (active = == false) {active = true; setTimeout (function () {lazyImages.forEach (function (lazyImage) {if ((lazyImage.getBoundingClientRect (). top <= window.innerHeight && lazyImage.getBoundingClientRect (). bottom> = 0 ) && getComputedStyle (lazyImage) .display! == "none") {lazyImage.src = lazyImage.dataset.src; lazyImage.srcset = lazyImage.dataset.srcset; lazyImage.classList.remove ("lazy"); .filter (function (image) {возвращаемое изображение! == lazyImage;}); if (lazyImages.length === 0) {document.removeEventListener ("scroll", lazyLoad); window.removeEventListener ("resize", lazyLoad) ; window.removeEventListener ("directionchange", lazyLoad);}}}); active = false;}, 200);}}; document.addEventListener ("scroll", lazyLoad); window.addEventListener ("resize", lazyLoad) ; window.addEventListener ("orie ntationchange ", lazyLoad); });

Этот код использует getBoundingClientRect в обработчике события прокрутки, чтобы проверить, присутствует ли какой-либо из элементов img.lazy в области просмотра. Вызов setTimeout используется для задержки обработки, а активная переменная содержит состояние обработки, которое используется для регулирования вызовов функций. Поскольку изображения загружаются лениво, они удаляются из массива элементов. Когда массив элементов достигает длины 0, код обработчика события прокрутки удаляется. Смотрите этот код в действии в этот пример CodePen ,

Хотя этот код работает практически в любом браузере, он имеет потенциальные проблемы с производительностью, так как повторяющиеся вызовы setTimeout могут быть расточительными, даже если код в них ограничен. В этом примере проверка выполняется каждые 200 миллисекунд при прокрутке документа или изменении размера окна независимо от того, есть изображение в окне просмотра или нет. Кроме того, утомительная работа по отслеживанию количества оставшихся элементов для отложенной загрузки и откреплению обработчика событий прокрутки остается за разработчиком.

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

Изображения в CSS

Хотя теги <img> являются наиболее распространенным способом использования изображений на веб-страницах, изображения также можно вызывать с помощью CSS. изображение на заднем плане собственность (и другие свойства). В отличие от элементов <img>, которые загружаются независимо от их видимости, поведение при загрузке изображений в CSS выполняется с большим количеством предположений. когда документ и CSS объектные модели а также визуализировать дерево встроенные, браузер проверяет, как CSS применяется к документу, прежде чем запрашивать внешние ресурсы. Если браузер определил правило CSS, включающее внешний ресурс, к документу, который он создает в данный момент, не применяется, браузер не запрашивает его.

Это умозрительное поведение может быть использовано для отсрочки загрузки изображений в CSS с помощью JavaScript, чтобы определить, когда элемент находится в области просмотра, и последующего применения к этому элементу класса, который применяет стилизацию, вызывая фоновое изображение. Это приводит к тому, что изображение загружается в момент необходимости, а не при начальной загрузке. Например, давайте возьмем элемент, который содержит большое фоновое изображение героя:

<div class = "lazy-background"> ​​<h1> Вот герой, чтобы привлечь ваше внимание! </ h1> <p> Вот копия героя, чтобы убедить вас купить вещь! </ p> <a href = "/ купить вещь "> купить вещь! </a> </ div>

Элемент div.lazy-background обычно содержит фоновое изображение героя, вызываемое CSS. Однако в этом примере отложенной загрузки мы можем изолировать свойство background-image элемента div.lazy-background через видимый класс, который мы добавим к элементу, когда он находится в области просмотра:

.lazy-background {background-image: url ("hero-placeholder.jpg"); / * Заполнитель изображения * /} .lazy-background.visible {background-image: url ("hero.jpg"); / * Финальное изображение * /}

Отсюда мы будем использовать JavaScript, чтобы проверить, находится ли элемент в области просмотра (с наблюдателем пересечения!), И добавим видимый класс в элемент div.lazy-background в это время, который загружает изображение:

document.addEventListener ("DOMContentLoaded", function () {var lazyBackgrounds = [] .slice.call (document.querySelectorAll (". lazy-background")); if ("IntersectionObserver" в окне) {пусть lazyBackgroundObserver = new IntersectionObb = function (records, наблюдатель) {records.forEach (function (entry) {if (entry.isIntersecting) {entry.target.classList.add ("visible"); lazyBackgroundObserver.unobserve (entry.target);}}); ); lazyBackgrounds.forEach (function (lazyBackground) {lazyBackgroundObserver.observe (lazyBackground);});}});

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

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

Как и с элементами изображения, мы также можем лениво загружать видео. Когда мы загружаем видео в нормальных условиях, мы делаем это с помощью элемента <video> (хотя альтернативный метод с использованием <img> возникла с ограниченной реализацией). Однако то, как мы лениво загружаем <video>, зависит от варианта использования. Давайте обсудим пару сценариев, каждый из которых требует своего решения.

Для видео, которое не воспроизводится автоматически

Для видео, воспроизведение которых инициируется пользователем (т. Е. Видео, которые не воспроизводятся автоматически), указав атрибут предварительной загрузки На элементе <video> может быть желательно:

<video controls preload = "none" poster = "one-do-not-simply-placeholder.jpg"> <source src = "one-do-not-simply.webm" type = "video / webm"> <source src = "one-do-not-simply.mp4" type = "video / mp4"> </ video>

Здесь мы используем атрибут preload со значением none, чтобы запретить браузерам предварительно загружать любые видеоданные. Чтобы занять место, мы используем атрибут poster, чтобы присвоить элементу <video> заполнитель. Причина этого в том, что поведение по умолчанию для загрузки видео может варьироваться от браузера к браузеру:

  • В Chrome по умолчанию для предварительной загрузки использовался автоматический режим, но в Chrome 64 теперь по умолчанию используются метаданные. Тем не менее, в настольной версии Chrome часть видео может быть предварительно загружена с помощью заголовка Content-Range. Firefox, Edge и Internet Explorer 11 ведут себя одинаково.
  • Как и в случае с Chrome для настольных компьютеров, версии Safari для настольных компьютеров 11.0 будут предварительно загружать диапазон видео. В версии 11.2 (в настоящее время версия Safari Tech Preview) предварительно загружаются только метаданные видео. В Safari на iOS видео никогда не загружается заранее ,
  • когда Режим сохранения данных включен, по умолчанию предзагрузка отсутствует.

Поскольку поведение браузера по умолчанию в отношении предзагрузки не задано в камне, вероятно, лучше всего быть явным. В этом случае, когда пользователь запускает воспроизведение, использование preload = "none" является самым простым способом отложить загрузку видео на всех платформах. Атрибут preload - не единственный способ отложить загрузку видеоконтента. Быстрое воспроизведение с предзагрузкой видео может дать вам некоторые идеи и понимание работы с воспроизведением видео в JavaScript.

К сожалению, это оказывается бесполезным, когда мы хотим использовать видео вместо анимированных GIF-файлов, о которых мы расскажем далее.

Для видео, выступающего в качестве замены анимированного GIF

Несмотря на то, что анимированные GIF-файлы широко используются, они по разным параметрам уступают видео эквивалентам, особенно по размеру выходного файла. Анимированные GIF-файлы могут занимать несколько мегабайт данных. Видео с аналогичным визуальным качеством, как правило, гораздо меньше.

Использование элемента <video> в качестве замены анимированного GIF не так просто, как элемент <img>. Анимированным GIF-файлам присуще три следующих поведения:

  1. Они играют автоматически при загрузке.
  2. Они зацикливаются непрерывно ( хотя это не всегда так ).
  3. У них нет звуковой дорожки.

Достижение этого с помощью элемента <video> выглядит примерно так:

<видео с автоматическим воспроизведением приглушенного цикла playsinline> <source src = "one-do-not-simply.webm" type = "video / webm"> <source src = "one-do-not-simply.mp4" type = "video / mp4 "> </ video>

Атрибуты autoplay, muted и loop не требуют пояснений. playsinline необходим для автоматического воспроизведения в iOS , Теперь у нас есть исправная замена видео в формате GIF, которая работает на разных платформах. Но как идти о ленивой загрузке? Chrome будет лениво загружать видео для вас , но вы не можете рассчитывать на все браузеры, чтобы обеспечить это оптимизированное поведение. В зависимости от вашей аудитории и требований к приложениям вам может потребоваться взять дело в свои руки. Для начала измените разметку <video> соответствующим образом:

<video autoplay muted loop playsinline width = "610" height = "254" poster = "one-do-not-simply.jpg"> <source src = "one-do-not-simply.webm" type = "video / webm "> <source src =" one-do-not-simply.mp4 "type =" video / mp4 "> </ video>

Вы заметите добавление атрибут плаката , который позволяет вам указать заполнитель, который будет занимать пространство элемента <video> до тех пор, пока видео не будет загружено с отложенной загрузкой. Как и в случае с нашими <img> примерами ленивой загрузки, приведенными ранее, мы сохраняем URL-адрес видео в атрибуте data-src для каждого элемента <source>. Оттуда мы будем использовать JavaScript, похожий на более ранние примеры отложенной загрузки изображений на основе наблюдателя пересечения:

document.addEventListener ("DOMContentLoaded", function () {var lazyVideos = [] .slice.call (document.querySelectorAll ("video.lazy")); if ("IntersectionObserver" в окне) {var lazyVideoObserver = новая функция IntersectionObserver ( (записи, наблюдатель) {records.forEach (function (video) {if (video.isIntersecting) {for (источник var в video.target.children) {var videoSource = video.target.children [source]; if (typeof videoSource .tagName === "string" && videoSource.tagName === "SOURCE") {videoSource.src = videoSource.dataset.src;}} video.target.load (); video.target.classList.remove ("lazy "); lazyVideoObserver.unobserve (video.target);}});}); lazyVideos.forEach (function (lazyVideo) {lazyVideoObserver.observe (lazyVideo);});}});

Когда мы лениво загружаем элемент <video>, нам нужно перебирать все дочерние элементы <source> и переворачивать их атрибуты data-src в атрибуты src. Как только мы это сделаем, нам нужно запустить загрузку видео, вызвав метод load элемента, после чего медиа начнет воспроизводиться автоматически в соответствии с атрибутом autoplay.

Используя этот метод, у нас есть видео решение, которое имитирует поведение анимированного GIF, но не требует такого же интенсивного использования данных, как анимированные GIF, и мы получаем ленивую загрузку этого контента.

Ленивая загрузка библиотек

Если вас не очень волнует, как ленивая загрузка работает под капотом, и вы просто хотите выбрать библиотеку и начать (и в этом нет ничего постыдного!), Есть множество вариантов на выбор. Многие библиотеки используют шаблон разметки, аналогичный тем, которые продемонстрированы в этом руководстве. Вот некоторые ленивые библиотеки загрузки, которые могут оказаться полезными:

  • lazysizes является полнофункциональной библиотекой с отложенной загрузкой, которая загружает изображения и встроенные кадры. Шаблон, который он использует, очень похож на примеры кода, показанные здесь, в том, что он автоматически привязывается к классу lazyload для элементов <img> и требует, чтобы вы указали URL-адреса изображений в атрибутах data-src и / или data-srcset, содержимое которые заменяются на атрибуты src и / или srcset соответственно. Он использует обозреватель пересечения (который вы можете заполнить, заполняя) и может быть расширен ряд плагинов делать ленивые загрузки видео.
  • lozad.js это суперлегкая опция, которая использует только наблюдателя пересечения. Как таковой, он обладает высокой производительностью, но его нужно будет заполнить, прежде чем использовать в старых браузерах.
  • Блази это еще один вариант, который позиционирует себя как легкий ленивый загрузчик (с весом 1,4 КБ). Как и в случае с lazysizes, для загрузки не требуются сторонние утилиты, и он работает для IE7 +. К сожалению, он не использует наблюдателя пересечения.
  • yall.js это библиотека, которую я написал, которая использует IntersectionObserver и использует обработчики событий. Он совместим с IE11 и основными браузерами.
  • Если вы ищете специфичную для React библиотеку отложенной загрузки, вы можете подумать реагируют-LazyLoad , Хотя он не использует средство наблюдения за пересечением, он предоставляет привычный метод отложенной загрузки изображений для тех, кто привык к разработке приложений с помощью React.

Каждая из этих библиотек отложенной загрузки хорошо документирована, с большим количеством шаблонов разметки для ваших различных задач отложенной загрузки. Если вы не тот, кто возится, возьмите библиотеку и уходите. Это займет наименьшее количество усилий.

Что может пойти не так

В то время как ленивая загрузка изображений и видео имеет положительные и ощутимые преимущества в производительности, ее не стоит воспринимать легкомысленно. Если вы ошиблись, это может привести к непредвиденным последствиям. Поэтому важно помнить о следующих проблемах:

Следи за сгибом

Может быть соблазнительно лениво загрузить каждый медиаресурс на странице с помощью JavaScript, но вы должны противостоять этому искушению. Все, что лежит над складкой, не должно быть лениво загружено. Такие ресурсы должны считаться критически важными активами и, следовательно, должны загружаться нормально.

Основной аргумент для загрузки критических медиаресурсов обычным способом вместо отложенной загрузки является то, что отложенная загрузка задерживает загрузку этих ресурсов до тех пор, пока DOM не станет интерактивным, когда скрипты закончат загрузку и начнут выполнение. Для изображений ниже сгиба это нормально, но было бы быстрее загружать критические ресурсы выше сгиба стандартным элементом <img>.

Конечно, в настоящее время не совсем понятно, когда веб-сайты просматриваются на многих экранах разных размеров. То, что лежит над складкой на ноутбуке, вполне может лежать под ним на мобильных устройствах. Нет пуленепробиваемых советов для оптимального решения этой проблемы в любой ситуации. Вам необходимо провести инвентаризацию критически важных ресурсов вашей страницы и загрузить эти изображения обычным способом.

Кроме того, вы, возможно, не захотите быть настолько строгим в отношении линии сгиба, как порог для запуска отложенной загрузки. Для ваших целей может оказаться более подходящим установить буферную зону на некотором расстоянии ниже сгиба, чтобы изображения начинали загружаться задолго до того, как пользователь прокрутит их в окне просмотра. Например, API-интерфейс наблюдателя пересечения позволяет указать свойство rootMargin в объекте параметров при создании нового экземпляра IntersectionObserver. Это эффективно дает элементам буфер, который запускает ленивое поведение загрузки до того, как элемент находится в области просмотра:

let lazyImageObserver = new IntersectionObserver (функция (записи, наблюдатель) {// Здесь идет код отложенной загрузки изображения}, {rootMargin: "0px 0px 256px 0px"});

Если значение для rootMargin выглядит аналогично значениям, которые вы указали бы для свойства CSS margin, то это так! В этом случае мы расширяем нижнее поле элемента наблюдения (по умолчанию область просмотра браузера, но его можно изменить на конкретный элемент с помощью свойства root) на 256 пикселей. Это означает, что функция обратного вызова будет выполняться, когда элемент изображения находится в пределах 256 пикселей от области просмотра, а это означает, что изображение начнет загружаться до того, как пользователь его увидит.

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

Сдвиг макетов и заполнителей

Ленивая загрузка носителя может вызвать смещение в макете, если заполнители не используются. Эти изменения могут дезориентировать пользователей и инициировать дорогостоящие операции макета DOM, которые потребляют системные ресурсы и способствуют увеличению риска. Как минимум, рассмотрите возможность использования сплошного цветового заполнителя, занимающего те же размеры, что и целевое изображение, или такие методы, как LQIP или же Sqip этот намек на содержимое элемента мультимедиа до его загрузки.

Для тегов <img> src должен изначально указывать на заполнитель до тех пор, пока этот атрибут не будет обновлен с помощью окончательного URL изображения. Используйте атрибут poster в элементе <video>, чтобы указать на изображение-заполнитель. Кроме того, используйте атрибуты width и height в тегах <img> и <video>. Это гарантирует, что переход от заполнителей к конечным изображениям не изменит размер элемента при загрузке носителя.

Задержка декодирования изображения

Загрузка больших изображений в JavaScript и добавление их в DOM может связать основной поток, что приведет к тому, что пользовательский интерфейс не будет реагировать в течение короткого периода времени во время декодирования. Асинхронное декодирование изображений с использованием метода декодирования перед вставкой их в DOM можно сократить этот вид мусора, но будьте осторожны: он еще не везде доступен, и это добавляет сложности ленивой логике загрузки. Если вы хотите использовать его, вам нужно проверить его. Ниже показано, как вы можете использовать Image.decode () с запасным вариантом:

var newImage = new Image (); newImage.src = "my-awesome-image.jpg"; if ("decode" in newImage) {// Необычная логика декодирования newImage.decode (). then (function () {imageContainer.appendChild (newImage);}); } else {// Обычная загрузка изображения imageContainer.appendChild (newImage); }

Проверять, выписываться эта ссылка CodePen чтобы увидеть код, похожий на этот пример в действии. Если большинство ваших изображений довольно маленькие, это может мало для вас сделать, но это, безусловно, может помочь сократить затрачиваемое время при ленивой загрузке больших изображений и вставке их в DOM.

Когда вещи не загружаются

Иногда медиа-ресурсы не загружаются по той или иной причине, и возникают ошибки. Когда это может произойти? Это зависит, но вот один гипотетический сценарий для вас: у вас есть политика кэширования HTML в течение короткого периода времени (например, пять минут), и пользователь посещает сайт, или у пользователя остается устаревшая вкладка, открытая в течение длительного периода времени. времени (например, несколько часов) и возвращается, чтобы прочитать ваш контент. В какой-то момент в этом процессе происходит перераспределение. Во время этого развертывания имя ресурса изображения изменяется из-за управления версиями на основе хеш-функции или полностью удаляется. К тому времени, когда пользователь лениво загружает изображение, ресурс становится недоступным, и, таким образом, происходит сбой.

Хотя это относительно редкие случаи, вам может потребоваться иметь план резервного копирования, если неудачная загрузка не удалась. Для изображений такое решение может выглядеть примерно так:

var newImage = new Image (); newImage.src = "my-awesome-image.jpg"; newImage.onerror = function () {// Решаем, что делать при ошибке}; newImage.onload = function () {// Загрузить изображение};

Что вы решите сделать в случае ошибки, зависит от вашего приложения. Например, вы можете заменить область заполнителя изображения кнопкой, которая позволяет пользователю снова попытаться загрузить изображение, или просто отобразить сообщение об ошибке в области заполнителя изображения.

Могут возникнуть и другие сценарии. Что бы вы ни делали, никогда не было бы плохой идеей сигнализировать пользователю, когда произошла ошибка, и, возможно, дать ему действие, которое следует предпринять, если что-то пойдет не так.

Доступность JavaScript

Не следует предполагать, что JavaScript всегда доступен. Если вы собираетесь загружать изображения с отложенной загрузкой, подумайте о предложении разметки <noscript>, которая будет отображать изображения в случае, если JavaScript недоступен. Простейший возможный запасной пример включает использование элементов <noscript> для обслуживания изображений, если JavaScript отключен:

<! - Изображение, которое в конечном итоге загружается с помощью JavaScript -> <img class = "lazy" src = "placeholder-image.jpg" src = "image-to-lazy-load.jpg" alt = "I ' m изображение! "> <! - Изображение, которое отображается, если JavaScript отключен -> <noscript> <img src =" image-to-lazy-load.jpg "alt =" Я изображение! "> </ noscript>

Если JavaScript отключен, пользователи увидят как заполнитель изображения, так и изображение, содержащееся с элементами <noscript>. Чтобы обойти это, мы можем поместить класс no-js в тег <html> следующим образом:

<html class = "no-js">

Затем мы помещаем одну строку встроенного скрипта в <head> перед тем, как любые таблицы стилей запрашиваются через теги <link>, которые удаляют класс no-js из элемента <html>, если JavaScript включен:

<Скрипт> document.documentElement.classList.remove ( "нет-JS"); </ скрипт>

Наконец, мы можем использовать некоторые CSS, чтобы просто скрыть элементы с классом lazy, когда JavaScript недоступен, например, так:

.no-js .lazy {display: none; }

Это не мешает загрузке изображений-заполнителей, но результат более желателен. Люди с отключенным JavaScript получают нечто большее, чем изображения-заполнители, что лучше, чем заполнители, и вообще никакого содержательного изображения.

Заключение

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

Насколько методы усовершенствования производительности идут, отложенная загрузка разумно бесспорная. Если на вашем сайте много встроенных изображений, это отличный способ сократить ненужные загрузки. Пользователи вашего сайта и участники проекта оценят это по достоинству!

Особая благодарность Франсуа Бофорт Дин Хьюм, Илья Григорк , Пол Ирландский , Адди Османи , Джефф Посник и Мартина Ширле за их ценные отзывы, которые значительно улучшили качество этой статьи.

Что такое ленивая загрузка?
Зачем лениво загружать изображения или видео, а не просто загружать их?
Что такое ленивая загрузка?
Зачем лениво загружать изображения или видео, а не просто загружать их?
Но как идти о ленивой загрузке?
Когда это может произойти?

Реклама

Популярные новости


Реклама

Календарь новостей

Реклама

Архив новостей

Реклама