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

Как использовать bLazy?

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

Далее, задаем всем картинкам, загрузку которых необходимо отложить класс . Адрес изображения в атрибуте меняем на прозрачную gif-заглушку с прозрачным фоном, закодированную в base64. Это так называемый плейсхолдер (placeholder) — то, что показывается до загрузки изображения. Такая заглушка не будет создавать лишних http-запросов. Оригинальный адрес изображения указываем в атрибуте .

Следующее, что мы сделаем — это подключим скрипт и инициализируем его.

Мы создали экземпляр класса . Он может принимать некоторые опции.

Lazy loading

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

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

Обзор

Вместе с ростом web-приложений драматически вырос объем и размеры ресурсов, отправляемых клиентскому приложению. С 2011 по 2019 медианный рост размеров ресурсов вырос с

400KB для настольных компьютеров и с

350KB для мобильных. А размер изображений вырос с

900KB для настольных компьютеров и со

850KB для мобильных.

Общий подход

Разделение кода (code splitting) JavaScript, CSS и HTML могут быть разделены на небольшие части, называемые чанками (chunks). При первоначальной загрузке приложения вы можете отправлять не цельное приложение, а только необходимые части, например, только каркас разметки. Данные для заполнения этого каркаса могут быть подгружены позже, например, с помощью AJAX. Есть два вида разделения кода:

  • Разделение по точкам входа (entrypoint)
  • Динамическое (dynamic import())

JavaScript

Указание типа «module» Любой тег скрипта с type=»module» рассматривается как JavaScript module, а его загрузка откладывается по умолчанию.

По умолчанию CSS считается ресурсом, блокирующим рендеринг (render blocking). Это означает, что браузер не будет отображать контент до тех пор, пока не будет построена объектная модель CSS (CSSOM). Поэтому CSS-файл должен быть небольшим, чтобы он был доставлен так быстро, насколько это возможно. Рекомендуется использовать медиавыражения, для того чтобы вместо одного монолитного CSS-файла грузить специализированные.

Также в целях ускорения CSS можно применять оптимизации (CSS optimizations).

Шрифты

По умолчанию, загрузка шрифтов откладывается на тот момент, пока дерево рендера (render tree) не сформировано полностью. Это приводит к тому, что текст страницы может появиться не сразу.

Вы можете переопределить такое поведение и загрузить шрифты заранее, используя <link rel=»preload»> , CSS font-display свойство или Font Loading API.

Изображения

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

Атрибут Loading Атрибут loading элемента <img> (или loading (en-US) атрибут для <iframe> (en-US)) могут быть использованы, чтобы указать браузеру на необходимость отложить загрузку изображений / iframe до тех пор, пока пользователь не доскроллит до них.

Событие load запускается, когда все другие необходимые ресурсы были загружены. В это время, возможно (или даже наиболее вероятно), что изображения не будут загружены, даже если пользователь доскроллит до изображений и они будут в visual viewport (en-US) .

Вы можете определить, было ли загружено то или иное изображение, проверив Boolean значение complete (en-US) .

Полифил Для использованиях в браузерах, которые не поддерживают данную технологию, рекомендуется использовать полифил: loading-attribute-polyfill

Intersection Observer API Intersection Observers позволяют вам узнать, как наблюдаемый вами элемент входит или выходит из зоны видимости браузера (viewport).

Обработчики событий (Event handlers) Intersection Observer API — относительно молодая технология, которая может не поддерживаться некоторыми устаревшими браузерами. Если поддержка браузеров важна для вас, есть несколько способов получить её:

Пример:

Обратите внимание:

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

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

<img class=»lazy» width=»100%» data-src=»photo.jpg» src=»thumb.jpg» />

1 <img class=»lazy»width=»100%»data-src=»photo.jpg»src=»thumb.jpg» />

.lazy {
filter: blur(5px) grayscale(1);
}

1
2
3

.lazy {

filterblur(5px)grayscale(1);

}

$(function() {
$(«img.lazy»).Lazy({
threshold: 0,
effect: ‘fadeIn’,
effectTime: 500,
afterLoad: function(element) {
element.css(«filter», «blur(0) grayscale(0)»);
}
});
});

1
2
3
4
5
6
7
8
9
10

$(function(){

$(«img.lazy»).Lazy({

threshold,

effect’fadeIn’,

effectTime500,

afterLoadfunction(element){

element.css(«filter»,»blur(0) grayscale(0)»);

}

});

});

Загрузка изображений при скроле и ресайзе #

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

Так только изображение загружено, удаляем класс у изображения. В момент, когда все изображения будут подгружены, можно так же отписываться от событий, так как они больше не нужны (если конечно приложение не SPA).

Вот рабочий пример этого подхода:

Достаточно подключить этот файл в ваше навороченное приложении, и lazy loading успешно настроен!

Либо воспользоваться библиотекой Paul-Browne/lazyestload.js, которая делает тоже самое, но так же умеет обрабатывать атрибут srсset и тег picture.

Теперь вы можете лениво смотреть,как загружаются ваши ленивые изображения

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

Поддержка

Тестировано:

  • IE11
  • EDGE
  • Chrome
  • Firefox

Для работы с IE11 необходимо использовать файл или , предварительно подключив Babel-polyfill, к примеру:

<script src="//cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js" crossorigin="anonymous"></script>
<script src="../dist/image-lazyload-babel.js"></script>

Подключать полифиллы надо до инициализации скриптов. На локальной машине такой метод не работает, только на боевом сервере.

Если не использовать полифиллы, будет ошибка . Она возникает из-за обработки babel-ом цикла .

Мы сознательно отказываемся от неиспользуемых браузеров, такие как IE или EDGE, но так как мы поддерживаем не только свои проекты, ввели такую приблуду для этого скрипта.

Как использовать скрипт

Для его работы не требуется никаких зависимостей типа jQuery. Он полностью самобытен. Достаточно подключить скрипт:

<script src="/image-lazyload.js"></script>
<img 
	srcset=" 622w,  1600w" 
	data-srcset=" 622w,  1600w" 
	src="" 
	class="g-image__lazyload">

Скрипт умеет собирать адаптивные изображения

И после инициализировать сбор изображений. Мы используем для этого класс:

<img class="g-image__lazyload" data-src="realimage.jpg" src="placeholder.jpg">

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

Затем, в конце документа (можно и в начале, но лучше после инициализации всей DOM-модели (отличаются способы запуска), необходимомо запустить сбор данных для обработки одним из вариантов, например:

<script>
	document.addEventListener('DOMContentLoaded', function () {
		'use strict';
		var preloadImagesList = document.querySelectorAll('.g-image__preload');
		preloadImages(preloadImagesList);
	})
</script>

Или

<script>
	window.onload = function () {
		'use strict';
		var preloadImagesList = document.querySelectorAll('.g-image__preload');
		preloadImages(preloadImagesList);
	}
</script>

Установка:

  • Подключаем библиотеку jQuery 1.7.2 + или Zepto 1.1.6 +
  • Подключаем плагин jquery.lazy.js или jquery.lazy.min.js

jquery.lazy доступен для подключения через cdnjs и jsDelivr CDN:

<!— jsDeliver —>
<script type=»text/javascript» src=»https://cdn.jsdelivr.net/gh/eisbehr-/jquery.lazy@1.7.10/jquery.lazy.min.js»></script>

1
2

<!— jsDeliver —>

<script type=»text/javascript»src=»//cdn.jsdelivr.net/gh/eisbehr-/jquery.lazy@1.7.10/jquery.lazy.min.js»></script>

<!— cdnjs —>
<script type=»text/javascript» src=»https://cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.min.js»></script>

1
2

<!— cdnjs —>

<script type=»text/javascript»src=»//cdnjs.cloudflare.com/ajax/libs/jquery.lazy/1.7.10/jquery.lazy.min.js»></script>

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

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

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

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

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

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

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

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

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

Либо же, использовать шрифты с иконками, такие как FontAwesome. Либо же, использовать SVG (от англ. Scalable Vector Graphics — масштабируемая векторная графика). Очень классная штука, рекомендую применять всё вышеперечисленное :). Сейчас еще мэйнстрим на формат изображений webp, которые значительно уменьшают вес изображений.

Вы спросите, а причём тут вообще это? Где статья? Чтобы добиться минимального веса страниц, нужно применять все эти рекомендации на своих проектах. И вот однажды, придумали такую классную штуку как Lazy Load. Суть её в том, что вы будете загружать только те изображения, которые попали в «вашу область видимости». Даже, если вы открыли страницу по середине и нажали F5, будут загружены именно те изображения, которые относятся к данному участку кода.

И это, как по мне, гениально. Если представить насколько меньше станет запросов к серверу, и насколько это уменьшит размер страниц, то это «отвал башки!»

Ленивая инициализация соединений

Наиболее часто в приложения используется работа с базами данных (MySQL, Memcache, Redis и т.п.). Обычно подключение к базе инициализируется где-то на старте приложения:

—memcache_connect(‘127.0.0.1’);—

#…

mysql_query(‘SELECT * FROM users WHERE id = 7’);

## Мы не использовали запросы к Memcache, хотя установили к нему соединение

Lazy loading в этом случае предусматривает установку соединения только в момент первого обращения к ресурсу. Например:

{

private static $connection;

public static function query($sql)

{

**if ( !self::$connection ) self::$connection = mysql_connect(‘127.0.0.1’, ‘root’, ‘123’);**

return mysql_query($sql);

}

}

#…

mysql::query(‘SELECT * FROM users WHERE id = 7’);

## Lazy loading для соединения с MySQL

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

{

private static $connection;

public static function get($key)

{

**if ( !self::$connection ) self::$connection = memcache_connect(‘127.0.0.1’);**

return memcache_get($key);

}

public static function set($key, $value)

{

**if ( !self::$connection ) self::$connection = memcache_connect(‘127.0.0.1’);**

return memcache_set($key, $value);

}

}

#…

memcache::get(‘user7’);

## Lazy loading для соединения с Memcache

Лучшие плагины для отложенной загрузки

1. Image Lazy Load

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

2.BJ Lazy Load

Этот ленивый плагин загрузки позволяет пользователям выбрать в постах изображения и эскизы, Gravatar, фреймы и заменяет содержимое с заполнителем. При выборе конкретного заполнителя вы можете пропустить изображения с разными классами. BJ Lazy Load также обслуживает различные размеры оптимизированных изображений и автоматически служит HiDPI изображениям для различных экранов HiDPI, как у сетчатке отображения Apple.

3. Jquery image lazy load

Jquery image lazy load добавляет Jquery отложенной загрузки различных изображений. Лучшая часть об этом плагине является то, что она очень проста в использовании. Все, что вам нужно сделать, это просто установить его и активировать. Изображения на сайте, которые вы посещаете будет автоматически загружаться, как вы прокрутите вниз до нижней части страницы. Вам не нужно ждать, чтобы изображения загружались в течение длительного времени. Как и при открытии веб-страницы и прокрутите до конца страницы, изображения уже загружены!

4. Rocket lazy load

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

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

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

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

iFrame может принимать форму сообщений и аудиоклипов, визуального контента, такого как изображения и видео, которые потребляют много ресурсов сервера. Также можете использовать iFrame для встраивания Google карты.

iFrames можно использовать на любом веб-сайте, независимо от используемой технологии. Но сосредоточимся на WordPress. Чтобы встроить iframe нужно использовать HTML-тег iFrame, в котором вы укажете источник контента. Пример:

<iframe src=»website.com»> </iframe>

1 <iframe src=»website.com»></iframe>

Отложенная загрузка iframe в WordPress с использованием встроенной отложенной загрузки браузера. Скопируйте и вставьте приведенный ниже код в файл functions.php.

add_filter( <span class=»hljs-string»>’save_post'</span>, <span class=»hljs-string»>’add_lazy_load'</span>, <span class=»hljs-number»>10</span>, <span class=»hljs-number»>3</span> );
<span class=»hljs-function»><span class=»hljs-keyword»>function</span> <span class=»hljs-title»>add_lazy_load</span>(<span class=»hljs-params»>$post_id, $post, $update</span>) </span>{
<span class=»hljs-keyword»> if</span> (wp_is_post_revision($post_id)) {
<span class=»hljs-keyword»> return</span>;
}
<span class=»hljs-keyword»> if</span> ( ! class_exists( <span class=»hljs-string»>’DOMDocument'</span>, <span class=»hljs-literal»>false</span> ) )
<span class=»hljs-keyword»> return</span>;
remove_action(<span class=»hljs-string»>’save_post'</span>, <span class=»hljs-string»>’add_lazy_load'</span>);
$post_status = get_post_status();

1
2
3
4
5
6
7
8
9

add_filter(<span class=»hljs-string»>’save_post'</span>,<span class=»hljs-string»>’add_lazy_load'</span>,<span class=»hljs-number»>10</span>,<span class=»hljs-number»>3</span>);

<span class=»hljs-function»><span class=»hljs-keyword»>function</span><span class=»hljs-title»>add_lazy_load</span>(<span class=»hljs-params»>$post_id,$post,$update</span>)</span>{

<span class=»hljs-keyword»>if</span>(wp_is_post_revision($post_id)){

<span class=»hljs-keyword»>return</span>;

}

<span class=»hljs-keyword»>if</span>(!class_exists(<span class=»hljs-string»>’DOMDocument'</span>,<span class=»hljs-literal»>false</span>))

<span class=»hljs-keyword»>return</span>;

remove_action(<span class=»hljs-string»>’save_post'</span>,<span class=»hljs-string»>’add_lazy_load'</span>);

$post_status=get_post_status();

Код автоматически добавит атрибут ‘loading = «lazy»‘ ко всем тегам img и iframe при создании новой записи или страницы.

Принцип работы атрибута loading

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

Событие load запускается, как только загружается полное изображение после первого запроса (для изображений размером менее 2 КБ) или после второго. Это событие может не запускаться для определенных изображений, из-за того, что не выполняется второй запрос.

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

Убедитесь, что ваши серверы поддерживают HTTP-заголовок Range: 0-2047 и ответьте кодом состояния 206 («Частичный контент»), чтобы исключить доставку полноразмерного изображения дважды.

Поговорим об отложенном контенте. Движок рендеринга Chrome Blink определяет, загрузку какого контента и на какой срок следует отложить. Полный список требований можно найти в документации. Ниже приводится краткое описание ресурсов, загрузка которых может быть отложена:

  • Изображения и фреймы на всех платформах, на которых установлено loading=»lazy».
  • Изображения на Chrome для Android, где включен Data Saver и которые удовлетворяют следующим требованиям:
    • loading=»auto» или значение unset;
    • атрибуты width и height больше 10px;
    • не созданы программно с помощью JavaScript.
  • Фреймы, которые удовлетворяют следующим требованиям:
    • loading=»auto» или значение unset;
    • из стороннего источника (домен или протокол, который отличается от тех, что были на странице встраивания);
    • если высота и ширина превышает 4 пикселя (чтобы предотвратить отложенную загрузку небольших следящих фреймов);
    • если для фреймов не установлено display: none или visibility: hidden (чтобы предотвратить отложенную загрузку небольших следящих фреймов);
    • если они не расположены за границами экрана из-за отрицательных координат x или

Еще немного о плейсхолдерах

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

В примере выше в качестве заглушки мы использовали прозрачную gif-картинку, закодированную в base64. Вообще, если не использовать прелодер, то во время загрузки мы вообще ничего не увидим. Есть варианты разнообразить этот момент.

Плейсхолдер доминирующего цвета

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

Источник изображения — https://manu.ninja/dominant-colors-for-lazy-loading-images

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

Плейсхолдер низкого качества (LQIP)

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

Плейсхолдер низкого качества (LQIP)

Вот HTML-код изображения.

Часто задаваемые вопросы

Какой плагин лучше всего подходит для отложенной загрузки изображений?

Если вы уже используете плагин кеша, который поддерживает ленивую загрузку (например, WP Rocket, SG Optimizer, W3TC, Swift, LiteSpeed), лучше сначала попробуйте их. В противном случае, Autoptimize или плагин Lazy Load от WP Rocket являются хорошими плагинами ленивой загрузки.

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

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

Как отключить ленивую загрузку на определенных страницах?

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

Что означает заменить YouTube Iframe предварительным изображением?

Если вы вставляете видео на свой сайт WordPress, «проигрыватель YouTube» загружается только после нажатия кнопки «Воспроизвести». Другими словами, единственное, что загружается изначально, это предварительное изображение.

Стоит ли лениво загружать изображения и видео?

Постоянная загрузка изображений при прокрутке страницы может раздражать пользователей. Тем не менее, все мои изображения оптимизированы до 100% в GTmetrix. Я лениво загружаю видео и заменяю iframe на изображение предварительного просмотра. Поскольку загрузка каждого встроенного видео может занять 2 секунды (намного тяжелее, чем изображение), польза от отложенной загрузки видео значительна.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Знай и умей
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: