Ленивая загрузка с помощью Lozad.js

Ленивая загрузка с помощью Lozad.js
Высокопроизводительный, легкий и настраиваемый ленивый загрузчик в чистом JS без зависимостей для изображений, iframes и многое другое, используя IntersectionObserver API


Lozad.js:

  • lazy loads elements performantly using pure JavaScript,
  • - это легкая библиотека, просто подключи https://cdn.jsdelivr.net/npm/lozadуменьшенная и gzipped,
  • - не ИМЕЕТ ЗАВИСИМОСТЕЙ :)
  • - позволяет также ленивую загрузку динамически добавляемых элементов,
  • - поддерживает <img>, <picture>, iframes, видео, аудио, адаптивные изображения, фоновые изображения и несколько фоновых изображений и т. Д.
  • - даже поддерживает LQIP (заполнитель изображений низкого качества)
  • - является полностью бесплатным и открытым исходным кодом.
  • - он будет перезагружен при изменении допустимых атрибутов.
  • Он написан с целью ленивой загрузки изображений, iframes, рекламы, видео или любого другого элемента с использованием недавно добавленного Intersection Observer API и MutationObserverс огромными преимуществами производительности.
Еще одна библиотека JavaScript с отложенной загрузкой. Почему?
Существующие библиотеки отложенной загрузки подключаются к событию прокрутки или используют периодический таймер и вызывают getBoundingClientRect() для элементов, которые необходимо загрузить с отложенной загрузкой. Однако этот подход очень медленный, поскольку каждый вызов getBoundingClientRect() заставляет браузер перерисовывать всю страницу и приводит к значительным перебоям в работе вашего веб-сайта.
Сделать это более эффективным и производительным - это то, для чего предназначен IntersectionObserver, и он приземлился в Chrome 51. IntersectionObservers позволяет узнать, когда наблюдаемый элемент входит или выходит из окна просмотра браузера.


Установить


# Вы можете установить lozad с помощью npm
$ npm install --save lozad

# Альтернативно вы можете использовать Yarn

$ yarn add lozad

# Другой вариант — использовать Bower

$ bower install lozad

Затем с помощью модуля bundler, такого как rollup или webpack, используйте, как и все остальное:

// использование модулей ES6

import lozad from 'lozad'

// использование модулей CommonJS

var lozad = require('lozad')

Или загрузить через CDNи включить в headтег вашей страницы.

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>

При загрузке с CDN вы можете найти библиотеку вкл window.lozad.

Применение

В HTML добавьте идентификатор к элементу (идентифицированный селектор по умолчанию — lozadclass):

<img class="lozad" data-src="image.png">

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

const observer = lozad(); // lazy loads elements with default selector as '.lozad'
observer.observe();или с помощью ссылки на элемент DOM:const el = document.querySelector('img');
const observer = lozad(el); // passing a `NodeList` (e.g. `document.querySelectorAll()`) is also valid
observer.observe();

или с пользовательскими опциями:

const observer = lozad('.lozad', {

    rootMargin: '10px 0px', // syntax similar to that of CSS Margin

    threshold: 0.1, // ratio of element convergence

   enableAutoReload: true // it will reload the new image when validating attributes changes

});

observer.observe();

Ссылка:

— Параметры IntersectionObserver: rootMargin.

— Параметры IntersectionObserver: пороговые значения.

или если вы хотите дать определение пользовательской функции для загрузки элемента:

lozad('.lozad', {
  load: function(el) {
        console.log('loading element');
// Пользовательская реализация для загрузки элемента
// e.g. el.src = el.getAttribute('data-src');
  }
});Если вы хотите расширить загруженное состояние элементов, вы можете добавить опцию «загружено»:
Примечание. Атрибут "data-loaded"="true" используется lozad для определения того, был ли ранее загружен элемент.lozad('.lozad', {
loaded: function(el) {
// Пользовательская реализация для загруженного элемента
        el.classList.add('loaded');
    }
});

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

const observer = lozad();
observer.observe();
// ... code to dynamically add elements
observer.observe(); // observes newly added elements as wellдля использования с адаптивными изображениями<!-- responsive image example -->
<img class="lozad" data-src="image.png" data-srcset="image.png 1000w, image-2x.png 2000w">

для использования с фоновыми изображениями

<!-- background image example -->
<div class="lozad" data-background-image="image.png">
</div>

для использования с несколькими фоновыми изображениями

<!-- multiple background image example -->
<div class="lozad" data-background-image="path/to/first/image,path/to/second/image,path/to/third/image">
</div>

для использования с адаптивными фоновыми изображениями (image-set)

<!-- responsive background image-set example -->
<div class="lozad" data-background-image-set="url('photo.jpg') 1x, url('photo@2x.jpg') 2x">
</div>

Чтобы изменить разделитель, разделяющий фоновые изображения:

<!-- custom delimiter for background images example -->
<div
  class="lozad"
  data-background-image="/first/custom,image,path/image.png-/second/custom,image,path/image.png"
  data-background-delimiter="-"
>
</div>

Если вы хотите загрузить изображения до их появления:const observer = lozad();


observer.observe();
const coolImage = document.querySelector('.image-to-load-first');
// ... trigger the load of a image before it appears on the viewport
observer.triggerLoad(coolImage);

Улучшение большого изображения
Иногда загрузка изображений занимает много времени. В этом случае вы можете добавить фон-заполнитель:

<img class="lozad" data-placeholder-background="red" data-src="image.png">

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

Пример с тегом изображения
Создайте структуру элемента сломанного изображения.
Браузер IE не поддерживает тег изображения! Вам необходимо установить data-iesrcattribute (только для ваших тегов изображений) с источником для браузера IE.
data-altattribute можно добавить к тегу изображения для использования в altattribute лениво загружаемых изображений.

<!-- For an element to be caught, add a block type that is different from the inline and some min-height for correct caught into view -->
<picture class="lozad" style="display: block; min-height: 1rem" data-iesrc="images/thumbs/04.jpg" data-alt="">
    <source srcset="images/thumbs/04.jpg" media="(min-width: 1280px)">
    <source srcset="images/thumbs/05.jpg" media="(min-width: 980px)">
    <source srcset="images/thumbs/06.jpg" media="(min-width: 320px)">
    <!-- NO img element -->
    <!-- instead of img element, there will be the last source with the minimum dimensions -->
    <!-- for disabled JS you can set <noscript><img src="images/thumbs/04.jpg" alt=""></noscript> -->
</picture>
Когда lozad загрузит этот элемент изображения, он исправит его.

Если вы хотите использовать заполнитель изображения (например, заполнитель изображения низкого качества), вы можете установить временный тег img внутри тега изображения. Он будет удален, когда lozad загрузит элемент изображения.

<picture class="lozad" style="display: block; min-height: 1rem" data-iesrc="images/thumbs/04.jpg" data-alt="">
<source srcset="images/thumbs/04.jpg" media="(min-width: 1280px)">
    <source srcset="images/thumbs/05.jpg" media="(min-width: 980px)">
    <source srcset="images/thumbs/06.jpg" media="(min-width: 320px)">
    <!-- you can define a low quality image placeholder that will be removed when the picture is loaded -->
    <img src="data:image/jpeg;base64,/some_lqip_in_base_64==">
</picture>Пример с видео<video class="lozad" data-poster="images/backgrounds/video-poster.jpeg">
    <source data-src="video/mov_bbb.mp4" type="video/mp4">
    <source data-src="video/mov_bbb.ogg" type="video/ogg">
</video>Пример с iframe<iframe data-src="embed.html" class="lozad"></iframe>

Вот и все, просто добавьте lozadкласс.

Пример класса переключения

<div data-toggle-class="active" class="lozad">
    <!-- content -->
</div>

active Класс будет переключен на элемент, когда он войдет в окно просмотра браузера.

Поддержка браузера

Доступно в последних браузерах. Если поддержка браузера недоступна, используйте https: // www. npmjs .com / package / intersection-observer

JavaScript / jQuery

/* lozad.js - v1.16.0 - 2020-09-06
*
* https://github.com/ApoorvSaxena/lozad.js
* Copyright (c) 2020 Apoorv Saxena; Licensed MIT */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.lozad=e()}(this,function(){"use strict";
/**
* Detect IE browser
* @const {boolean}
* @private
*/var g="undefined"!=typeof document&&document.documentMode,f={rootMargin:"0px",threshold:0,load:function(t){if("picture"===t.nodeName.toLowerCase()){var e=t.querySelector("img"),r=!1;null===e&&(e=document.createElement("img"),r=!0),g&&t.getAttribute("data-iesrc")&&(e.src=t.getAttribute("data-iesrc")),t.getAttribute("data-alt")&&(e.alt=t.getAttribute("data-alt")),r&&t.append(e)}if("video"===t.nodeName.toLowerCase()&&!t.getAttribute("data-src")&&t.children){for(var a=t.children,o=void 0,i=0;i<=a.length-1;i++)(o=a[i].getAttribute("data-src"))&&(a[i].src=o);t.load()}t.getAttribute("data-poster")&&(t.poster=t.getAttribute("data-poster")),t.getAttribute("data-src")&&(t.src=t.getAttribute("data-src")),t.getAttribute("data-srcset")&&t.setAttribute("srcset",t.getAttribute("data-srcset"));var n=",";if(t.getAttribute("data-background-delimiter")&&(n=t.getAttribute("data-background-delimiter")),t.getAttribute("data-background-image"))t.style.backgroundImage="url('"+t.getAttribute("data-background-image").split(n).join("'),url('")+"')";else if(t.getAttribute("data-background-image-set")){var d=t.getAttribute("data-background-image-set").split(n),u=d[0].substr(0,d[0].indexOf(" "))||d[0];// Substring before ... 1x
u=-1===u.indexOf("url(")?"url("+u+")":u,1===d.length?t.style.backgroundImage=u:t.setAttribute("style",(t.getAttribute("style")||"")+"background-image: "+u+"; background-image: -webkit-image-set("+d+"); background-image: image-set("+d+")")}t.getAttribute("data-toggle-class")&&t.classList.toggle(t.getAttribute("data-toggle-class"))},loaded:function(){}};function A(t){t.setAttribute("data-loaded",!0)}var m=function(t){return"true"===t.getAttribute("data-loaded")},v=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:document;return t instanceof Element?[t]:t instanceof NodeList?t:e.querySelectorAll(t)};return function(){var r,a,o=0<arguments.length&&void 0!==arguments[0]?arguments[0]:".lozad",t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=Object.assign({},f,t),i=e.root,n=e.rootMargin,d=e.threshold,u=e.load,g=e.loaded,s=void 0;"undefined"!=typeof window&&window.IntersectionObserver&&(s=new IntersectionObserver((r=u,a=g,function(t,e){t.forEach(function(t){(0<t.intersectionRatio||t.isIntersecting)&&(e.unobserve(t.target),m(t.target)||(r(t.target),A(t.target),a(t.target)))})}),{root:i,rootMargin:n,threshold:d}));for(var c,l=v(o,i),b=0;b<l.length;b++)(c=l[b]).getAttribute("data-placeholder-background")&&(c.style.background=c.getAttribute("data-placeholder-background"));return{observe:function(){for(var t=v(o,i),e=0;e<t.length;e++)m(t[e])||(s?s.observe(t[e]):(u(t[e]),A(t[e]),g(t[e])))},triggerLoad:function(t){m(t)||(u(t),A(t),g(t))},observer:s}}});

Разное по оптимизации загрузки

Предварительная загрузка скриптов и стилей

<link href="/hostcmsfiles/jquery/jquery.min.js" rel="preload" as="script">
<link href="/hostcmsfiles/jquery/jquery.min.css" rel="preload" as="css">

Атрибут async

Async используется для того, чтобы указать браузеру, что скрипт может быть выполнен асинхронно.Парсеру HTML нет необходимости останавливаться, когда он достигает тега <script> для загрузки и выполнении. Выполнение может произойти после того, как скрипт будет получен параллельно с разбором документа.
<script async src="script.js">

Атрибут defer

Атрибут defer указывает браузеру, что скрипт должен быть выполнен после того, как HTML-документ будет полностью разобран.
<script defer src="script.js">
Как и при асинхронной загрузке скриптов — файл может быть загружен, в то время как HTML-документ парсится. Однако, даже если файл скрипта будет полностью загружен ещё до того, как парсер закончит работу, он не будет выполнен до тех пор, пока парсер не отработает до конца.
<img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-bg="{dir}{image_large}" alt="{name}"/>