Отложенная загрузка контента

Принцип работы скриптов lazy-load

Lazy-load или «ленивая» загрузка — это способ отображения контента на сайте, когда элементы, появление которых определяет внешний ресурс, загружаются не сразу вместе с запрашиваемой страницей, а асинхронно — по мере необходимости. К подобным элементам относятся, например, изображения () и фреймы (). Их объединяет наличие атрибута , указывающего на источник ресурса.

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

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

Основы работы большинства скриптов «ленивой» загрузки описываются подобным алгоритмом:

  1. Элементы, которые необходимо загружать асинхронно, встраиваются на страницу с другим, временным значением атрибута (или вовсе без него, что неправильно с точки зрения валидации кода). Как правило, временное значение содержит адрес шаблона, который по весу на порядок легче оригинального исходника.
  2. При необходимости в атрибут вставляется оригинальный, исходный адрес ресурса. Как правило, эта замена может осуществляться двумя путями:
    1. По требованию пользователя, когда для элемента наступают события или .
    2. Автоматически при попадании элемента в пользовательский viewport путём проверки события , а также и для мобильных устройств.

Таким образом, при использовании lazy-load при первой загрузке страницы производится не одновременно несколько запросов к разным внешним ресурсам, а всего один — к временному шаблону, указанному в атрибуте , который кэшируется браузером, и только затем при необходимых условиях (наступление заданных событий) для выбранных элементов устанавливается их оригинальный .

Существует и иной подход, при котором можно обойтись без замещающих шаблонов для оригинальных ресурсов: элементы не встраиваются на страницу изначально, а создаются динамически в процессе просмотра или определенных действий пользователя (подобные манипуляции с DOM используются, например, при подключении скриптов статистики Google Analytics или Яндекс. Метрики) либо клонируются из Shadow DOM (по такому принципу работает элемент ).

Reviews

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>lass=»plugin-reviews»>

I’m using WordPress’ native Youtube embed in Classic editor. No effect on the video.

We have pages with multiple videos and that slowed down the page load and increased network traffic. This plugin improved it a lot. Reduced blocking of some pages with seconds and reduced the page load from 3MB to 1,3MB.

Lazy Load for Videos plugin was easy to install with good support from their webpage. Made my webpage superfast. At least 3 seconds faster on mobilepeed. Score went from 59 to 90 on speedtesting. Very happy. Thanks!

I like the simpler approach of this plugin when compared to the other plugins that do the same thing.

There’s only one thing that I would like to update in this plugin, the CSS, that can definitely be improved and an option to dequeue all stylesheets would be awesome.

Thanks for the awesome plugin! Great work.

I did everything I could think of to get my page speed score for the pages with videos up and went nowhere fast. With this though I went from a 34 in google page speed insights, to a 78, with just this one plugin. Highly recommend. Can’t go wrong for YouTube videos.

… it just works.

The description doesn’t seem to mention oembed … but it works for those too.

Browsers with disabled JavaScript

As JavaScript may be disabled in the browser (e.g. it may be a feature phone with limited javascript support or browser
with Noscript addon), it is usually recommended to add a fallback image in tag, mark initial image with
attribute and hide it using CSS (otherwise browsers with disabled javascript will display both images).
Lazy Load XT plugin removes this class ( option) at image initialization. So, final code should be
like:

img.lazy {
  display none;
}
<img class="lazy" data-src="lazy.jpg" width="100" height="100">
<noscript><img src="lazy.jpg" width="100" height="100"></noscript>

We recommend to keep the order of attributes in both tags, because of such a code will be effectively gzipped.

Alternative approach is based on tagging images/videos with tag. It is realized using
addon and is described in
(note that this approach is experimental and currently is not compatible with AJAX).

Avoid lazy-loading images that are in the first visible viewport #

You should avoid setting for any images that are in the first visible viewport.

It is recommended to only add to images which are positioned below the fold, if possible. Images that are eagerly loaded can be fetched right away, while images which are loaded lazily the browser currently needs to wait until it knows where the image is positioned on the page, which relies on the IntersectionObserver to be available.

In Chromium, the impact of images in the initial viewport being marked with on Largest Contentful Paint is fairly small, with a regression of <1% at the 75th and 99th percentiles compared to eagerly loaded images.

Generally, any images within the viewport should be loaded eagerly using the browser’s defaults. You do not need to specify for this to be the case for in-viewport images.

Скрипт lazy load. Ленивая загрузка изображений при прокрутке страницы

Ниже представлена полная версия скрипта lazy load, который осуществляет ленивую загрузку изображений по мере прокрутки страницы

document.addEventListener("DOMContentLoaded", function() {
  var Images= [].slice.call(document.querySelectorAll("img.lazyloading"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting){
          let Image= entry.target;
          Image.src = Image.dataset.src;
          Image.srcset = Image.dataset.srcset;
          Image.onload = function(){
               this.classList.remove("lazyloading");
               delete this.dataset.src;
               delete this.dataset.srcset;
          }
          lazyImageObserver.unobserve(Image);
        }
      });
    });

    Images.forEach(function(Image) {
      lazyImageObserver.observe(Image);
    });
  } else {
    // дополнительный метод который будет активирован при отсутствии IntersectionObserver
  }
});

Опишем последовательность выполненных действий:

  • Дожидаемся полной загрузки DOM документа, чтобы сразу отобразить пользователю текстовую часть страницы
  • Создаем коллекцию всех изображений требующих ленивую загрузку. Если такие картинки отсутствует — прекращаем работу скрипта.
  • Проверяем существование метода IntersectionObserver. В случае если метод отсутствует — применяем альтернативный способ ленивой загрузки изображений
  • Во время прокрутки страницы определяем картинки, которые пересекли видимую область страницы и загружаем их. Для того чтобы подгружать изображения чуть раньше попадания в видимую область устанавливаем параметр rootMargin. За счет этого пользователь не должен заметить нашего эффекта
  • Удаляем ненужные классы и атрибуты и перестаем отслеживать загруженную картинку за счет свойства unobserve

Intersection Observer

Intersection Observer API предоставляет асинхронное наблюдение изменений в видимости элементов или относительной видимости двух элементов по отношению друг к другу.

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

Так выглядит отложено загруженный элемент изображения.

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

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

Сначала создаем экземпляр Intersection Observer:

IO принимает функцию в конструкторе, которая обладает двумя параметрами: первый содержит массив, состоящий из элемента для наблюдения, а второй содержит экземпляр IO.

  • entries: содержит в массиве элементы, находящиеся в окне просмотра браузера.
  • imgObserver: экземпляр IntersectionObserver.

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

Затем нужно проверить, находится ли каждый entry в окне просмотра. Если entry пересекается с окном просмотра, то устанавливаем значение атрибута data-src для атрибута src в элементе img.

Проверяем, находится ли entry в окне видимости браузера . Если да, то сохраняем экземпляр HTMLImgElement элемента img в переменной lazyImage. Затем устанавливаем атрибут src, присвоив его значению набора данных . При этом изображение, сохраненное в , загружается в элемент img. Предыдущее изображение заменяется в браузере реальным изображением.

Теперь нужно вызвать imageObserver для начала наблюдения за элементами img:

Объединяем все элементы с классом в документе и передаем в .

выбирает массив элементов и прослушивает их, чтобы узнать о пересечении их видимости с браузером.

Чтобы увидеть демо отложенной загрузки, нужно запустить проект Node:

Создайте файл index.html:

Добавьте в него следующее:

У нас есть 5 отложенных изображений, каждое из которых содержит lazy_img.jpg, а также несколько реальных изображений для загрузки.

Необходимо создать свои изображения:

Я создал lazy_img.jpg в Windows Paint, а реальные изображения () взял из Pixabay.com.

Обратите внимание, что я добавил console.log в функцию обратного вызова IntersectionObserver. Благодаря этому можно узнать, для каких изображений применяется отложенная загрузка

Для использования файла index.html нужно установить http-сервер:

Теперь добавляем свойство в раздел сценариев в package.json.

Теперь запустите в терминале.

Откройте браузер и перейдите к . Загруженный index.html будет выглядеть следующим образом:

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

Другие изображения не загружаются, так как они не находятся в представлении браузера.

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

Это серьезно повлияет на производительность сайта.

Чтобы решить эту проблему, нужно отписать IntersectionObserver от img, для которого уже загружено реальное изображение, а также удалить класс lzy из элемента img.

Редактируем код следующим образом:

Использование ленивой загрузки

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

Также отложенная загрузка применяется к видео, скриптам и комментариям. По сути, перемещение файлов JavaScript в футер страницы – это способ ускорения загрузки страницы.

Наверно, вы замечали, что YouTube загружает комментарии только после прокручивания страницы вниз. Таким образом обеспечивается быстрая загрузка видео.

Бесконечная прокрутка – это альтернатива классической пагинации страниц. При ее использовании дополнительные записи загружаются во время скроллинга страницы вниз. Это можно заметить на Pinterest и Pocket.

Это удобно для пользователей, ведь не нужно все время нажимать на номер следующей страницы.

Improved data-savings and distance-from-viewport thresholds #

As of July 2020, Chrome has made significant improvements to align the image lazy-loading distance-from-viewport thresholds to better meet developer expectations.

On fast connections (e.g 4G), we reduced Chrome’s distance-from-viewport thresholds from to and on slower connections (e.g 3G), changed the threshold from to . This change achieves two things:

  • behaves closer to the experience offered by JavaScript lazy-loading libraries.
  • The new distance-from-viewport thresholds still allow us to guarantee images have probably loaded by the time a user has scrolled to them.

You can find a comparison between the old vs. new distance-from-viewport thresholds for one of our demos on a fast connection (4G) below:

Old thresholds. vs new thresholds:

and the new thresholds vs. LazySizes (a popular JS lazy-loading library):

To ensure Chrome users on recent versions also benefit from the new thresholds, we have backported these changes so that Chrome 79 — 85 inclusive also uses them. Please keep this in mind if attempting to compare data-savings from older versions of Chrome to newer ones.

We are committed to working with the web standards community to explore better alignment in how distance-from-viewport thresholds are approached across different browsers.

Images should include dimension attributes

While the browser loads an image, it does not immediately know the image’s dimensions, unless these are explicitly specified. To enable the browser to reserve sufficient space on a page for images, it is recommended that all tags include both and attributes. Without dimensions specified, layout shifts can occur, which are more noticeable on pages that take some time to load.

Alternatively, specify their values directly in an inline style:

The best practice of setting dimensions applies to tags regardless of whether or not they are being loaded lazily. With lazy-loading, this can become more relevant. Setting and on images in modern browsers also allows browsers to infer their intrinsic size.

In most scenarios images still lazy-load if dimensions are not included, but there are a few edge cases you should be aware of. Without and specified, image dimensions are 0×0 pixels at first. If you have a gallery of such images, the browser may conclude that all of them fit inside the viewport at the start, as each takes up practically no space and no image is pushed offscreen. In this case the browser determines that all of them are visible to the user and decides to load everything.

Also, specifying image dimensions decreases the chances of layout shifts happening. If you are unable to include dimensions for your images, lazy-loading them can be a trade-off between saving network resources and potentially being more at risk of layout shift.

While lazy-loading in Chromium is implemented in a way such that images are likely to be loaded once they are visible, there is still a small chance that they might not be loaded yet. In this case, missing and attributes on such images increase their impact on Cumulative Layout Shift.

Take a look at this demo to see how the attribute works with 100 pictures.

Images that are defined using the element can also be lazy-loaded:

Although a browser will decide which image to load from any of the elements, the attribute only needs to be included to the fallback element.

Extendability

Lazy Load XT plugin may be easily extended using , , and handlers. Some examples are
listed below.

Some effects may be easily added by using and css classes. For example, to display animated
spinner while image is loading, just load css file:

<linkrel="stylesheet"href="jquery.lazyloadxt.spinner.css">

To add fade-in animation just load CSS file:

<linkrel="stylesheet"href="jquery.lazyloadxt.fadein.css">
<linkrel="stylesheet"href="animate.min.css">
$.lazyLoadXT.onload.addClass='animated bounceOutLeft';

Lazy Load XT checks that an image is in viewport in both vertical and horizontal dimensions, so that it is easy to
make lazy loading of images in horizontal scroller. Let’s assume that your html markup of scroller is something like

<divclass="wrapper"><imgdata-src="/path/to/image/1"width="600"height="300"><imgdata-src="/path/to/image/2"width="600"height="300"><imgdata-src="/path/to/image/3"width="600"height="300"><imgdata-src="/path/to/image/4"width="600"height="300"></div>

with following CSS rules to make scrollable in horizontal direction and images to be alined:

.wrapper{overflow-xscroll;overflow-yhidden;white-spacenowrap;}.wrapper > img{displayinline-block;    *displayinline;    *zoom1;}
$.lazyLoadXT.scrollContainer='.wrapper';

Using Lazy Load XT it is easily to get «infinite scroll» effect. Just put a marker element at the end of list

<divid="marker"><div>

and load next part of elements in handler, e.g.:

$(document).ready(function(){$('#marker').on('lazyshow',function(){$.ajax({...}).done(function(responseText){$(window).lazyLoadXT();$('#marker').lazyLoadXT({visibleOnlyfalse, checkDuplicatesfalse});});}).lazyLoadXT({visibleOnlyfalse});});

The code below allows you to use attribute for screens with 3x density (e.g. Samsung Galaxy S4),
for 2x density (e.g. iPhones 4+), and for 1.5x density (e.g. HTC Incredible S).

(function($,dpr){if(dpr>1)$.lazyLoadXT.srcAttr='data-src-'+(dpr >2?'3x'(dpr >1.5?'2x''1.5x'));})(jQuery,window.devicePixelRatio||1);

If you use jQuery-based AJAX navigation and don’t like to change existing AJAX callbacks,
you can apply lazy loading to new loaded content using event. Note that may not work correctly because of content is not added to the page at the time of
event, that’s why it’s better to postpone initialization by :

$(window).on('ajaxComplete',function(){setTimeout(function(){$(window).lazyLoadXT();},50);});

Lazy Load XT uses Data-URI-encoded transparent image for images outside of viewport (though this image may be visible
during fast page scroll or in print preview). As IE 6 and 7 don’t support Data-URI, you can change image for that
browsers:

if(parseInt(navigator.userAgent.toLowerCase().split('msie')1||8,10)<8)$.lazyLoadXT.blankImage='//upload.wikimedia.org/wikipedia/en/d/d0/Clear.gif';

Native Lazy Loading

For Chrome users, you can use the native lazy loading feature to lazy load web resources in the modern web app.

The new attribute which brings native and lazy-loading to the web:

<!-- Lazy-load an offscreen image when the user scrolls near it -->
<img src="unicorn.jpg" loading="lazy" alt=".."/>

<!-- Load an image right away instead of lazy-loading -->
<img src="unicorn.jpg" loading="eager" alt=".."/>

<!-- Browser decides whether or not to lazy-load the image -->
<img src="unicorn.jpg" loading="auto" alt=".."/>

<!-- Lazy-load images in <picture>. <img> is the one driving image 
loading so <picture> and srcset fall off of that -->
<picture>
  <source media="(min-width: 40em)" srcset="big.jpg 1x, big-hd.jpg 2x">
  <source srcset="small.jpg 1x, small-hd.jpg 2x">
  <img src="fallback.jpg" loading="lazy">
</picture>

<!-- Lazy-load an image that has srcset specified -->
<img src="small.jpg"
     srcset="large.jpg 1024w, medium.jpg 640w, small.jpg 320w"
     sizes="(min-width: 36em) 33.3vw, 100vw"
     alt="A rad wolf" loading="lazy">

<!-- Lazy-load an offscreen iframe when the user scrolls near it -->
<iframe src="video-player.html" loading="lazy"></iframe>

However, you may still need a third-party JavaScript library to implement the lazy load functionality on cross-browser projects.

Опции

Опции передаются в формате — ключ/значение. Примерно следующим образом:

breakpoints

breakpoints (array, по умолчанию — false) — применяется для адаптивных изображений, имеющие контрольные точки, т. е. в зависимости от размера экрана показываем ту или иную картинку.

container

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

error

error (функция function(ele, msg), по умолчанию возвращает false) — функция возвращает два сообщения: missing и invalid, если мы сделали что-то не так. Missing — если атрибут пустой или вообще не указан. Invalid — если в атрибуте указан не валидный адрес изображения.

errorClass

errorClass (строка, по умолчанию — b-error) — данный класс добавится элементу если пойдет что-то не так. Например, если параметр error выше вернет missing или invalid.

loadInvisible 

loadInvisible (булево, по умолчанию — false) — если по каким-то причинам вы хотите загрузить скрытые изображения, то передайте значение — true.

offset

offset (число, по умолчанию — 100) — этот параметр отвечает за то, с каким отступом будут загружены изображения. По умолчанию — 100, значит изображение загрузится за 100 пикс до его появления в видимой части.

root

root (объект, по умолчанию — document) — корневой объект может быть изменен. Честно сказать, не совсем понял этот пункт, вернее его предназначение.

saveViewportOffsetDelay

saveViewportOffsetDelay (число, по умолчанию — 50) — задержка для срабатывания функции saveViewportOffsetDelay при изменении размера окна браузера. По умолчанию выставлено 50 мс.

selector

selector (строка, по умолчанию — b-lazy) — селектор для изображений, которые вы хотите загружать лениво. Например для всех изображений вы можете указать просто — img. Если хотите указать несколько селекторов, то перечислите их через запятую, например — .img-1, .img-2, .img-3…

separator

separator (символ, по умолчанию — |) — используется, если вы хотите указать несколько изображений в атрибуте для retina-дисплеев. Например, .

success

success (функция function(ele), по умолчанию возвращает — false) — обратный вызов, когда изображения все загрузились. Полезно, если мы после загрузки изображений хотим выполнить какие либо действия.

successClass

successClass (строка, по умолчанию — b-loaded) — класс, который добавляется изображению, когда оно успешно загрузилось.

validateDelay

validateDelay (число, по умолчанию — 25) — как часто должна вызываться функция валидации при проктуртке/ресайзинге страницы. По умолчанию — 25 мс.

Некоторые подробные примеры реализации вышеописанных опций вы сможете найти на сайте разработчика. Я лишь приведу некоторые.

Why browser-level lazy-loading? #

According to HTTPArchive, images are the most requested asset type for most websites and usually take up more bandwidth than any other resource. At the 90th percentile, sites send about 4.7 MB of images on desktop and mobile. That’s a lot of cat pictures.

Currently, there are two ways to defer the loading of off-screen images:

  • Using the Intersection Observer API
  • Using , , or

Either option can let developers include lazy-loading functionality, and many developers have built third-party libraries to provide abstractions that are even easier to use. With lazy-loading supported directly by the browser, however, there’s no need for an external library. Browser-level lazy loading also ensures that deferred loading of images still works even if JavaScript is disabled on the client.

?‍? Getting started — HTML

In order to make your content be loaded by LazyLoad, you must use some attributes instead of the actual attributes. Examples below.

Lazy responsive image with and :

<img
  alt="A lazy image"
  class="lazy"
  data-src="lazy.jpg"
  data-srcset="lazy_400.jpg 400w, 
    lazy_800.jpg 800w"
  data-sizes="100w"
/>

To have a low quality placeholder, add the attribute pointing to a very small version of the image. E.g. .

Lazy responsive image with hi-dpi support using the tag:

<picture>
  <source media="(min-width: 1200px)" data-srcset="lazy_1200.jpg 1x, lazy_2400.jpg 2x" />
  <source media="(min-width: 800px)" data-srcset="lazy_800.jpg 1x, lazy_1600.jpg 2x" />
  <img alt="A lazy image" class="lazy" data-src="lazy.jpg" />
</picture>

To have a low quality placeholder, add the attribute pointing to a very small version of the image to the tag. E.g. .

Lazy responsive image with automatic WebP format selection, using the tag:

<picture>
  <source
    type="image/webp"
    data-srcset="lazy_400.webp 400w, 
      lazy_800.webp 800w"
    data-sizes="100w"
  />
  <img
    alt="A lazy image"
    class="lazy"
    data-src="lazy.jpg"
    data-srcset="lazy_400.jpg 400w, 
      lazy_800.jpg 800w"
    data-sizes="100w"
  />
</picture>

To have a low quality placeholder, add the attribute pointing to a very small version of the image to the tag. E.g. .

Lazy background image

IMPORTANT NOTE: To display content images on your pages, always use the tag. This would benefit the SEO and the accessibility of your website. To understand if your images are content or background, ask yourself: «would my website user like to see those images when printing out the page?». If the answer is «yes», then your images are content images and you should avoid using background images to display them.

Single background image:

<div class="lazy" data-bg="lazy.jpg"></div>

Single background, with HiDPI screen support:

<div class="lazy" data-bg="lazy.jpg" data-bg-hidpi="lazy@2x.jpg"></div>

Multiple backgrounds:

<div
  class="lazy"
  data-bg-multi="url(lazy-head.jpg), 
    url(lazy-body.jpg), 
    linear-gradient(#fff, #ccc)"
>
  ...
</div>

Please note that you must use to wrap the URLs in your attributes.

Multiple backgrounds, HiDPI screen support:

<div
  class="lazy"
  data-bg-multi="url(lazy-head.jpg),
    url(lazy-body.jpg),
    linear-gradient(#fff, #ccc)"
  data-bg-multi-hidpi="url(lazy-head@2x.jpg),
    url(lazy-body@2x.jpg),
    linear-gradient(#fff, #ccc)"
>
  ...
</div>

Please note that you must use to wrap the URLs in your attributes.

Lazy video

<video class="lazy" controls width="620" data-src="lazy.mp4" data-poster="lazy.jpg">
  <source type="video/mp4" data-src="lazy.mp4" />
  <source type="video/ogg" data-src="lazy.ogg" />
  <source type="video/avi" data-src="lazy.avi" />
</video>

Please note that the video poster can be lazily loaded too.

? Tips & tricks

Occupy space and avoid content reflow

It’s a good idea to make sure that your lazy images occupy some space even before they are loaded, otherwise the elements will be shrinked to zero-height, causing your layout to reflow and making lazyload inefficient.

Vertical padding trick

<div class="image-wrapper">
  <img class="lazy image" alt="An image" data-src="lazy.jpg" />
</div>
.image-wrapper {
  width: 100%;
  height: ;
  padding-bottom: 150%;
  /*  image height / width * 100% */
  position: relative;
}
.image {
  width: 100%;
  height: auto;
  position: absolute;
}

Inline SVG

If you can’t use the vertical padding trick for some reason, the best option is to use an SVG placeholder of the same ratio of the lazy images.

<img
  src="data:image/svg+xml,%3Csvg 
    xmlns='http://www.w3.org/2000/svg' 
    viewBox='0 0 3 2'%3E%3C/svg%3E"
  data-src="//picsum.photos/900/600"
  alt="Lazy loading test image"
/>

Alternatively (but less efficiently) you can use a tiny, scaled-down version of your images as a placeholder, stretching them to the final size of the images, and obtain a blur-up effect when the full images load.

Using a placeholder image will also make sure that browsers don’t show your content instead of the images before the lazy-loading starts.

Usage

First of all it’s necessary to load jQuery and Lazy Load XT script. There are two versions of Lazy Load XT:

  1. , standard version for lazy loading of images only.

  2. , version with included video addon for lazy loading of both images and videos.

To make media elements (, , , ) to be lazy loaded, rename attribute to .
It is highly recommended to set and attributes. Optionally you can add a placeholder to bypass
HTML validators:

<script src="jquery.js"></script>
<script src="jquery.lazyloadxt.js"></script>

<img data-src="lazy.jpg" width="100" height="100">

PS. In directory you can found , it is initial LazyLoadXT version of minimal size
with excluded support of on* handlers, lazy* events, option and addons.

Example of page preparation in PHP

Instead of manipulating tags directly (that is to replace by ,
add fallback image, etc.), it’s possible to do html page postprocessing using language.
Here is example of how to do it using PHP:

/* PHP */
function addLazyLoading($html) {
  $dom = new DOMDocument();
  if (!@$dom->loadHTML('<?xml encoding="UTF-8">' . $html)) // trick to set charset
    return $html;
  foreach ($dom->childNodes as $item)
    if ($item->nodeType === XML_PI_NODE) {
      $dom->removeChild($item);
      break;
    }
  $dom->encoding = 'UTF-8';
  $images = $dom->getElementsByTagName('img');
  $blankImage = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
  for ($i = $images->length - 1; $i >= ; $i--) {
    $node     = $images->item($i);
    $clone    = $node->cloneNode();
    $noscript = $dom->createElement('noscript');
    $noscript->appendChild($clone);
    $node->parentNode->insertBefore($noscript, $node);
    $node->setAttribute('data-src', $node->getAttribute('src'));
    $node->setAttribute('src',      $blankImage);
    $node->setAttribute('class',    trim($node->getAttribute('class') . ' lazy'));
  }
  $newHtml = $dom->saveHTML();
  if (!$newHtml)
    return $html;
  return $newHtml;
}

Что такое отложенная загрузка изображений

Скрытые изображения — это картинки, которые находятся за пределами видимости веб-страницы (viewport), не прибегая к прокрутке. То есть те картинки, которые нам еще предстоит посмотреть, когда мы будем прокручивать страницу вниз или вверх. Отложенную загрузку еще называют ленивой загрузкой изображений (lazy load images).

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

Все эти действия сводятся к оптимизации сайта, то есть на ускорение загрузки отдельных страниц сайта. Этот фактор учитывается при тестировании сайта в сервисе pageSpeed Insights от гугла.

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

Как реализовать

Рекомендации Google по реализации lazy loading для картинок

Рекомендации Google для картинок зависят от способа реализации медиаконтента на сайте: встроенные или в CSS. Для встроенных в тег в Справке поисковой системы рекомендуется использовать:

  • обработчик событий (например, scroll или resize) – он подходит, если важна совместимость браузеров;
  • API-интерфейса обозревателя пересечений – не нужно писать свой код, достаточно зарегистрировать наблюдателя, однако работает не на всех браузерах.

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

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

Готовые решения

В сети есть 5 готовых решений реализации «отложенной загрузки» для изображений:

Lazy loading от David Walsh

Это стандартный и наиболее простой вариант реализации «отложенной загрузки». Действие скрипта заключается в том, что он заменяет атрибут src на data-src в теге . Реализация выглядит следующим образом:

Элементы img, содержащие атрибуты data-src, скрыты в CSS. После того как картинки будут загружены, они плавно отображаются с применением переходов:

Затем JavaScript передаёт всем тегам img атрибут src, которые в итоге получают значение атрибута data-src. После загрузки всех изображений, data-src убирается из img:

Загрузка с прогрессивным улучшением от Robin Osborne

Разработчик предлагает «ленивую загрузку» на основе прогрессивного улучшения. В его решении lazy loading на JS будет считаться улучшением для HTML и CSS.

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

Плагин bLazy.js на простом JS

Стандартная реализация отложенной загрузки этим методом выглядит так:

Среди преимуществ скрипта: он мало весит, работает с несколькими изображениями одновременно, чтобы сэкономить трафик и уменьшить количество запросов на сервер. Также он поддерживает браузеры устаревших версий, в том числе IE 7 и 8 версии.

Плагин Lazy Load XT jQuery

Подойдёт для написания своего скрипта для «ленивой загрузки». Если нужно реализовать lazy loading только для картинок, рекомендуем воспользоваться упрощённой версией.

Для реализации «отложенной загрузки» с помощью этого плагина нужно добавить jQuery-библиотеку перед закрывающимся тегом и указать jquery.lazyloadxt.js.

Есть альтернативный вариант, который позволяет не использовать весь плагин. Это облегчённый скрипт jqlight.lazyloadxt.min.js:

Плагин активируется автоматически или в ручном режиме. В последнем случае нужно ввести:

Размытое изображение от Craig Buckler

Есть несколько вариантов реализации «ленивой загрузки» с эффектом размытости. Наиболее популярный и простой в реализации – Craig Buckler.

У техники высокая производительность: затрачивает немного больше 1 байта JS-кода и 463 байта CSS. Для работы не нужны дополнительные фреймворки или библиотеки. Есть прогрессивное улучшение для поддержки устаревших браузеров или подгрузки картинок при сломанном JavaScript.

Посмотреть код можно в репозитории на GitHub.

3 плагина для WordPress

BJ Lazy Load

Количество установок: более 90 тыс. Последнее обновление: год назад.

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

Lazy Load by WP Rocket

Количество установок: более 20 тыс. Последнее обновление: 17 часов назад.

Плагин работает с миниатюрами, всеми изображениями. Подгружает контент только тогда, когда он становится видимым пользователю. Вес скрипта – 10 КБ. Не использует JavaScript библиотеку jQuery.

Loading Page with Loading Screen

Количество установок: более 10 тыс. Последнее обновление: 2 дня назад.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector