Гибридная отложенная загрузка: постепенный переход к нативной отложенной загрузке

Опубликовано: 2022-03-10
Краткий обзор ↬ Нативная ленивая загрузка приходит в Интернет. Поскольку он не зависит от JavaScript, он произведет революцию в том, как мы сегодня лениво загружаем контент, упрощая разработчикам ленивую загрузку изображений и фреймов. Но это не та функция, которую мы можем полифилить, и потребуется некоторое время, прежде чем ее можно будет использовать во всех браузерах. В этой статье вы узнаете, как это работает и как вы можете постепенно заменить отложенную загрузку на основе JavaScript ее родной альтернативой благодаря гибридной отложенной загрузке.

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

«Да, отличные новости, но нам придется подождать, пока их не поддержат все браузеры».

Если это первое, что пришло вам в голову, продолжайте читать. Я постараюсь убедить вас в обратном.

Давайте начнем со сравнения нативной ленивой загрузки и старой доброй загрузки, управляемой JavaScript.

Нативная загрузка в сравнении с отложенной загрузкой, управляемой JavaScript

Ленивая загрузка — это способ повысить производительность веб-сайта или веб-приложения за счет максимального увеличения скорости рендеринга изображений и фреймов (а иногда и видео) в верхней части страницы за счет отсрочки загрузки контента в нижней части страницы.

Ленивая загрузка, управляемая JavaScript

Для ленивой загрузки изображений или фреймов очень распространена практика их разметки путем замены надлежащего атрибута src аналогичным атрибутом данных, data-src , а затем полагаться на решение JavaScript для определения того, когда изображения / фреймы получают близко к видимой части веб-сайта (обычно из-за того, что пользователь прокрутил вниз) и скопировать атрибуты данных в нужные, а затем запустить отложенную загрузку их контента.

 <img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Еще после прыжка! Продолжить чтение ниже ↓

Нативная отложенная загрузка

Согласно собственной спецификации ленивой загрузки (все еще находящейся в разработке), если вы хотите лениво загружать изображения или фреймы с помощью встроенной функции ленивой загрузки, вам просто нужно добавить атрибут loading=lazy в соответствующий тег.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Эдди Османи много писал об этой теме в своей статье «Отложенная загрузка нативных изображений для Интернета!» в котором он заявил, что команда Google Chrome уже разрабатывает эту функцию и намерена добавить ее в Chrome 75.

Другие браузеры на основе Chromium, такие как Opera и Microsoft Edge, также выиграют от этой разработки, получив ту же функцию в своем первом обновлении на основе Chromium 75.

Начните с нативной ленивой загрузки

В случае, если изображения вашего веб-сайта загружаются сразу при посадке на страницу без отложенной загрузки, вы можете включить (где поддерживается) встроенную отложенную загрузку на своем веб-сайте так же просто, как добавить атрибут HTML. Атрибут loading сообщает браузерам, какие изображения важно загрузить немедленно, а какие можно загружать лениво, когда пользователи прокручивают страницу вниз. Тот же атрибут можно применить к iframe.

Чтобы сообщить браузерам, что конкретное изображение важно, чтобы они могли загрузить его как можно скорее, вы должны добавить атрибут loading="eager" в тег img . Лучше всего делать это для основных изображений — как правило, для тех, которые будут отображаться в верхней части сгиба.

 <img src="rabbit.jpg" alt="Fast rabbit" loading="eager">

Чтобы указать браузерам, что изображение должно загружаться лениво, просто добавьте атрибут loading="lazy" . Это лучшая практика, только если вы делаете это только для вторичных изображений — обычно для тех, которые будут отображаться ниже сгиба.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

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

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

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

Бесполезно для полифилла

Когда новая браузерная технология выпускается для одного браузера, сообщество открытого исходного кода обычно выпускает полифилл JavaScript, чтобы обеспечить ту же технологию для остальных браузеров. Например, полифил IntersectionObserver использует элементы JavaScript и DOM для координации Element.getBoundingClientRect() , чтобы воспроизвести поведение собственного API.

Но случай с нативной ленивой загрузкой отличается, потому что полифилл JavaScript для loading="lazy" должен предотвратить загрузку контента браузерами, как только они найдут URL-адрес в разметке изображения или iframe. JavaScript не контролирует этот начальный этап рендеринга страницы, поэтому встроенная ленивая загрузка полифилла невозможна.

Гибридная ленивая загрузка

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

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

Чтобы выполнить гибридную ленивую загрузку, вам нужно разметить ленивый контент, используя атрибуты data вместо реальных (например, в ленивой загрузке на основе JavaScript) и добавить атрибут loading="lazy" .

 <img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">

Тогда вам потребуется JavaScript. Во-первых, вам нужно определить, поддерживает ли браузер нативную ленивую загрузку . Затем выполните одно из следующих действий для каждого элемента с атрибутом loading="lazy" :

  • Если поддерживается собственная отложенная загрузка, скопируйте значение атрибута data-src в атрибут src ;
  • Если это не поддерживается, инициализируйте скрипт отложенной загрузки JavaScript или плагин, чтобы делать это, когда элементы входят в область просмотра.

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

 if ('loading' in HTMLImageElement.prototype)

Если это так, просто скопируйте значение атрибута src из data-src . Если это не так, инициализируйте любой сценарий отложенной загрузки по вашему выбору.

Вот фрагмент кода, который это делает.

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>

Вы можете найти и протестировать приведенный выше код в этой живой демонстрации.

Тем не менее, это очень простой сценарий, и все может усложниться, если вы используете дополнительные атрибуты или теги для получения адаптивных изображений (например, srcset и sizes или даже теги picture и source ).

Небольшая сторонняя помощь

В течение последних четырех лет я поддерживал скрипт отложенной загрузки с открытым исходным кодом под названием « vanilla-lazyload », и через пару дней после того, как Эдди Османи написала о нативной отложенной загрузке, сообщество отреагировало, спросив меня, может ли мой скрипт действовать как полифилл.

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

Начиная с версии vanilla-lazyload , вы можете просто установить для параметра use_native значение true , чтобы включить гибридную ленивую загрузку. Скрипт весит всего 2,0 КБ в сжатом виде и уже доступен на GitHub, npm и jsDelivr.

  • Познакомьтесь с vanilla-lazyload на GitHub

Демо

Вы можете начать экспериментировать со встроенной отложенной загрузкой уже сегодня, загрузив Chrome Canary или Microsoft Edge Insider ( канал разработчика ), а затем установив флаги «Включить отложенную загрузку изображений» и «Включить отложенную загрузку кадров». Чтобы включить эти флаги, введите about:flags в поле URL вашего браузера и найдите «ленивый» в поле поиска.

Нативная демонстрация ленивой загрузки

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

  • Протестируйте нативную демо-версию ленивой загрузки

Чего ожидать : все изображения загружаются одновременно, но с разными HTTP-ответами. Изображения с кодом ответа 200 загружаются с готовностью, а изображения с кодом ответа 206 загружаются только частично, чтобы получить начальную информацию об изображениях. Затем эти изображения будут полностью загружены с кодом ответа 200 при прокрутке вниз.

Демонстрация гибридной ленивой загрузки

Чтобы проанализировать, как работает гибридная отложенная загрузка, вы можете начать играть со следующей демонстрацией. Здесь используется [email protected] , а для параметра use_native установлено значение true :

  • Демонстрация гибридной ленивой загрузки

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

Обратите внимание, что vanilla-lazyload под капотом использует IntersectionObserver API, поэтому вам потребуется полифиллировать его в Internet Explorer и более поздних версиях Safari. Это не имеет большого значения, если полифилл не предоставляется, потому что в этом случае vanilla-lazyload просто загрузит все изображения сразу.

Примечание . Подробнее читайте в главе «Использовать или не использовать полифилл» в файле readme vanilla-lazyload .

Попробуйте гибридную ленивую загрузку на своем веб-сайте

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

HTML-разметка

Простейшая разметка изображения производится двумя атрибутами: src и alt .

Для изображений выше сгиба вы должны оставить атрибут src и добавить атрибут loading="eager" .

 <img src="important.jpg" loading="eager" alt="Important image">

Для изображений, расположенных ниже сгиба, вы должны заменить атрибут src атрибутом данных data-src и добавить атрибут loading="lazy" .

 <img data-src="lazy.jpg" loading="lazy" alt="A lazy image">

Если вы хотите использовать адаптивные изображения, сделайте то же самое с srcset и sizes .

 <img alt="A lazy image" loading="lazy" data-src="lazy.jpg">

Если вы предпочитаете использовать тег picture , измените srcset , sizes и src также в source тегах.

 <picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>

Тег picture также можно использовать для выборочной загрузки формата WebP для ваших изображений.

Примечание . Если вы хотите узнать больше об использовании vanilla-lazyload , прочтите HTML-раздел «Начало работы» в его файле readme.

JavaScript-код

Прежде всего, вам нужно включить vanilla-lazyload на свой сайт.

Вы можете загрузить его из CDN, например jsDelivr:

 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Или вы можете установить его с помощью npm:

 npm install vanilla-lazyload@12

Также можно использовать async скрипт с автоматической инициализацией; загрузите его как модуль ES, используя type="module" или загрузите его как AMD, используя RequireJS. Узнайте больше о способах включения и использования vanilla-lazyload в разделе сценария «Начало работы» в файле readme.

Затем в код JavaScript вашего веб-сайта/веб-приложения включите следующее:

 var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });

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

Все вместе, используя async скрипт

Чтобы собрать все это воедино и использовать async скрипт для максимальной производительности, обратитесь к следующему коду HTML и JavaScript:

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Вот и все! С помощью этих очень простых и легких шагов вы включите гибридную ленивую загрузку на своем веб-сайте!

Важные рекомендации

  • Применяйте ленивую загрузку только к тем изображениям, которые, как вы знаете, вероятно, будут отображаться в нижней части страницы. Нетерпеливо загружайте те, которые находятся выше сгиба, чтобы максимизировать производительность. Если вы просто примените ленивую загрузку ко всем изображениям на странице, вы снизите производительность рендеринга.
  • Используйте CSS, чтобы зарезервировать место для изображений перед их загрузкой. Таким образом, они будут продвигать остальную часть контента ниже. Если вы этого не сделаете, большее количество изображений будет размещено в верхней части страницы раньше, чем это необходимо, что вызовет их немедленную загрузку. Если вам нужен CSS-трюк, чтобы сделать это, вы можете найти его в разделе советов и трюков в файле readme vanilla-lazyload .

Плюсы и минусы

НАТИВНАЯ ЛЕНИВАЯ ЗАГРУЗКА
ПЛЮСЫ
  • JavaScript не требуется;
  • Никаких головных болей при настройке, это просто работает;
  • Не нужно резервировать место для изображений с помощью трюков CSS;
МИНУСЫ
  • Сегодня это работает не во всех браузерах;
  • Начальная полезная нагрузка выше из-за предварительной выборки начальных 2 КБ для каждого изображения.
ЛЕНИВАЯ ЗАГРУЗКА НА JAVASCRIPT
ПЛЮСЫ
  • Прямо сейчас он работает стабильно во всех браузерах;
  • Вы можете делать очень настраиваемые трюки с пользовательским интерфейсом, такие как эффект размытия или отложенная загрузка.
МИНУСЫ
  • Он использует JavaScript для загрузки вашего контента.
ГИБРИДНАЯ ЛЕНИВАЯ ЗАГРУЗКА
ПЛЮСЫ
  • Это дает вам возможность включить и протестировать встроенную ленивую загрузку, где она поддерживается;
  • Он включает ленивую загрузку во всех браузерах;
  • Вы можете прозрачно удалить зависимость скрипта, как только нативная поддержка ленивой загрузки станет широко распространенной.
МИНУСЫ
  • Он по-прежнему использует JavaScript для загрузки вашего контента.

Подведение итогов

Я очень рад, что встроенная ленивая загрузка появится в браузерах, и я не могу дождаться, когда все поставщики браузеров реализуют ее!

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

Попробуйте! Не забудьте пометить / посмотреть vanilla-lazyload на GitHub и поделиться своими мыслями в разделе комментариев.

Дальнейшее чтение на SmashingMag:

  • Теперь вы видите меня: как отложить, отложить загрузку и действовать с IntersectionObserver
  • Ленивая загрузка модулей JavaScript с ConditionerJS
  • Контрольный список производительности внешнего интерфейса 2019 (PDF, Apple Pages, MS Word)
  • Как улучшение производительности веб-сайта может помочь спасти планету