Ленивая загрузка контента на лендинге. Управление загрузкой изображений

28.10.2023

Привет, в этой статье Я рассказываю как сделать ленивую загрузку изображений на любом сайте и на любом движке, а так же показываю пример на базе WordPress, аналогичный DLE, Drupal, Prestashop и другим популярным CMS.

Немного теории

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

Все заметили как вконтакте быстро грузится!?

Пример из жизни

Представь что у тебя на странице около 200 изображений (это может быть страница категорий в интернет магазине или раздел фотогалереи или даже запись в блоге). Пусть каждое изображение размером 250 на 250 пикселей и весит 50 Кб. Итого получаем почти 10 мб изображений (200 шт * 50 кб = 10’000 кб) и 200 запросов к серверу.

Зачем нагружать пользователя таким количеством информации сразу? Давай покажем ему только первые 8 изображений, а остальные по мере того как они ему понадобятся. Загрузка страницы в этом случае пройдёт в разы быстрее. Кроме того, большинство твоих пользователей вообще не будут скролить страницу до конца. Им будет достаточно этих 8 уже загружённых изображений!

Отличный пример реализации ленивой загрузки:

Wildberries это сайт с ежедневной милионной посещаемостью Представляешь себе нагрузку на сервер?

Внедрение (установка) ленивой загрузки

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

2. Загрузи файлы из архива на свой сервер, например в корень твоего сайта, чтобы файлы были доступны ссылке вроде tvoisite.ru/js/jquery.js

3. Подключи эти файлы в шаблон (для WordPress это файл header.php, а для DLE это main.tpl), а сразу после них вставь код. У тебя должно получиться нечто похожее на это:

$(function() { $("img").lazyload({ failurelimit: 10, threshold: 150, placeholder: "/img/dot.gif", effect: "fadeIn" }); });

Эти строчки нужно включить до элемента

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

5. Готово! Но ты должен настроить этот скрип под себя, вот параметры которые ты можешь настроить:

  • failurelimit: 10 — скрипт останавливает поиск после того, как обнаружит 10 изображений на странице. Если у твоей страницы достаточно сложная разметка, то укажи здесь число побольше.
  • threshold: 150 — порог открытия изображения. Если установить значение 0, то изображение начнёт загружаться только в тот момент когда появится на странице. В нашем случае изображение начнёт загружать заранее, т.е. за 150 пикселей до появления в зоне видимости.
  • placeholder: «/img/dot.gif» — путь к фоновой картинке, которая будет отображаться пока не загрузится само изображение. Здесь можно установить какую-нибудь анимацию загрузки.
  • effect: «fadeIn» — эффект появления графического элемента.
Подвожу итог

Я использую технологию отложенной загрузки в двух своих интернет магазинах. Это позволяет мне экономить ресурсы сервера, а так же не заставлять пользователя томится в ожидании полной загрузки страницы. В своё время с помощью этой технологии Я уменьшил скорость загрузки своего интернет магазина с 6 до 2 секунд. Только вдумайтесь: в три раза быстрее!

А ты используешь ленивую загрузку?

Важной частью работы любого сайта является скорость его загрузки у пользователя в браузере. Тут правило одно - чем быстрее, тем лучше. Оптимизировать проект не всегда возможно, и тут к нам на выручку приходят некоторые хитрости. Сегодня мы поговорим о «ленивой загрузке» картинок на сайте, и использовать будем jQuery плагин Lazy Load .

Самый наглядный и лучший пример работы Lazy Load - это лента любой социальной сети. Сам принцип прост, подгружать изображения постепенно, по мере прокрутки страницы пользователем. Если вдаться немного в теорию, то при открытии HTML страницы её загрузка происходит в два этапа. Во-первых, загружается структура документа, а во-вторых, происходит дозагрузка встраиваемых файлов (в нашем случае - картинок). Lazy Load вклеивает вместо наших изображений пустышки с минимальным весом, путем генерации их через data:image;base64 , а при прокрутке уже догружает основной медиа контент. Таким образам сокращается время загрузки страницы, что очень хорошо!

ИСХОДНИКИ

Шаг 1. HTML

Итак, давайте начнем с подключения скриптов:


Добавим изображения на страницу:



При добавлении разметки важно указать атрибуты width и height , иначе работать скрипт не будет или указать ширину и высоту в стилях картинки.

Шаг 2. JS

Теперь вызываем новый метод после загрузки HTML документа:

$("img.lazyImg").lazyload({
effect: "fadeIn"
});
});

У плагина есть несколько полезных настроек:

  • event - событие, по которому начинать загрузку картинки (click или scroll);
  • effect - анимация отображения (show или fadeIn);
  • container - указывается контейнер, в котором нужно искать изображения;
  • placeholder - в этот параметр можно установить свою заглушку.

Изображения на страницу загружаются двумя основными способами: посредством тега HTML и с помощью CSS свойства background-image . Поэтому мы сначала посмотрим на пример с тегом, а потом перейдем к рассмотрению фоновых изображений CSS .

Ленивая загрузка изображений с помощью тега img

Начнем с простой HTML разметки для вставки изображений на страницу.

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

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

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

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

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

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

В этом методе используются обработчики для следующих событий: scroll, resize и orientationChange. Событие прокрутки (scroll ) определяет текущее положение пользователя на странице, когда он перематывает ее. События resize и orientationChange важны в одинаковой степени. Событие resize возникает, когда изменяется размер окна браузера, а событие orientationChange вызывается, когда ориентация устройства меняется с ландшафтного на портретный режим и обратно.

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

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

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

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

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

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

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

В этой статье мы поговорим об «ускорении» загрузки сайта при помощи «отложенной загрузки изображений» на Javascript, приведем примеры реализации для известных framework ов mootools и jQuery. Это особенно актуально для сайтов, которые используют изображения высокого качества (новостные порталы, сайты, посвященные фотографии, дизайну, клипарту, социальные сети, объемные блоги и т.п.)

Отложенная загрузка изображений при помощи javascript с использованием mootools, jQuery

Какие неприятности нас ожидают во время загрузки изображений? При обычной загрузке изображения, если встречается битое или отсутствующее изображение, или картинка загружается с другого источника, или картинка «слишком медленно» грузится – сайт «подвисает».

Его загрузка не продолжится до тех пор, пока мы не получим текущее изображение, или не истечет минутный timeout. Что же видит посетитель? Зачастую – ничего, просто белый экран, или обрывочную часть сайта. Будет ли он терпеть такую «выходку» сайта и вернется ли когда-нибудь снова?

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

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

Идея, в общем-то, простая. Есть такое событие в javascript «domready» . Которое наступает во время получения полной структуры html документа и еще до полной загрузки страницы. Так вот, после наступления этого события мы получаем список нужных изображений , «сбрасываем» атрибут src каждой картинки, устанавливая для него значение, например, анкор: #. Src же изображения сохраняем в отдельном атрибуте изображения, например, longDesc . Скрываем картинку , назначая css правило: visibility: hidden .

После полной загрузки страницы по событию window.onload каждой картинке «возвращаем» её родной атрибут src (что, по сути, вызывает «загрузку» оригинального изображения). Картинки одна за другой начинают «появляться» на странице.

Усовершенствуем идею отложенной загрузки

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

Что же еще? Было бы хорошо визуально для посетителя показать , что на странице что-то происходит. Например, что отложенные изображения грузятся . Для этого достаточно вставить некий элемент span сразу после изображения , назначить ему css класс preloader и в рамках css стилизовать элемент .

После чего назначить background ом тематическое интуитивно понятное динамическое изображение загрузки , скажем, в формате gif. Теперь после полной загрузки текущего изображения по наступлению события объекта image onload удалить элемент span.preloader и отобразить само изображение , присвоив картинке css правило: visibility: visible;

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

А вот здесь всплывает проблема номер один. Это удивительно! Но до сих пор ни один браузер не поддерживает нормально у объекта image событие onload! Событие наступает стихийно.

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

Эмуляция события onload для объекта Image

Итак, подумав, мы пришли к выводу, что изображение считается загруженным только тогда, когда у него атрибуты длинна и высота: width, height становятся отличными от 0 . Но здесь, как обычно, обрадовал Internet Explorer, который при неудачной попытке загрузить изображение «подставляет» вместо него свое «по умолчанию» с красным крестиком, у которого тоже есть длинна и высота.

Исследовав дальше свойства объекта image, мы обнаружили, что нужно также проверять свойство complete – которое показывает, было ли изображение загружено полностью. Кроме этого обрадовали Safari, Google Chrome, построенные на движке Webkit, по их мнению было ли изображение загружено или нет – без разницы, complete всегда true.

Так что приходится обрабатывать для каждого изображения события onerror, onabort , и в случае их возникновения (при ошибке загрузки), присваивать атрибутам width, height изображения 0 значение. Итак, в итоге мы проверяем эти три свойства объекта image через определенный интервал времени.

Как только complete = true, а width, height отличны от 0 – изображение загружено полностью и не является битым. Но, чтобы не «плодить» бесконечные интервальные события, мы определим максимальное число времени, через которое отменим интервальное событие проверки для текущего изображения, будем считать, что изображение получить невозможно, и скроем объект его загрузки.

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

Реализация отложенной загрузки изображений на Mootools и jQuery

Позвольте Вам привести два исполнения отложенной загрузки изображений на Mootools и jQuery.

Mootools 1.1 – 1.4.4:

/** delayed image load by Black#FFFFFF **/ loadWait = 30000; loadCheck = 300; preloadObjects = "img"; notImagesLoaded = ; excludeImages = false; //excludeImages = "exclude" function getScreenHeight(){ var myHeight = 0; if(typeof(window.innerHeight) == "number") { //Non-IE myHeight = window.innerHeight; } else if(document.documentElement && (document.documentElement.clientHeight || document.documentElement.clientHeight)){ //IE 6+ in "standards compliant mode" myHeight = document.documentElement.clientHeight; } else if(document.body && (document.body.clientHeight || document.body.clientHeight)) { //IE 4 compatible myHeight = document.body.clientHeight; } return myHeight; } function preloadOther(){ var l = notImagesLoaded.length; var currentExists = false; for(var i = 0; i < l; i ++){ var item = notImagesLoaded[i]; if(item){ loadImage(item); currentExists = true; }; }; if(!currentExists){ notImagesLoaded = ; window.removeEvent("scroll",preloadOther); }; }; function imagesPreloader(){ $$(preloadObjects).each(function(item){ if(item.nodeName.toLowerCase() == "img" && (typeof excludeImages == "undefined" || excludeImages == false || (item.className.indexOf(excludeImages) == -1))){ item.longDesc = item.src; item.src = "#"; var preloaderElt= new Element("span",{ styles:{"display":"inline-block"}}); $(preloaderElt).className = "preloader "+item.className; preloaderElt.inject(item,"before"); loadImage(item); }; }); window.addEvent("scroll",preloadOther); }; function loadImage(item){ var pos = $(item).getPosition(); var ItemOffsetTop = typeof pos == "object" && typeof pos.y != "undefined" ? pos.y: 0; var documentScrollTop = $(window).getScrollTop(); var scrHeight= getScreenHeight(); if(ItemOffsetTop loadWait){ $clear(this.storePeriod); this.storePeriod = false; if(typeof this.loadedCount != "undefined" && notImagesLoaded){ notImagesLoaded = false; }; $(this).setStyles({"display":"none","visibility":"hidden"}); if(typeof $(this.previousSibling).destroy == "function"){ $(this.previousSibling).destroy(); } else { $(this.previousSibling).remove(); } } }.periodical(loadCheck,item); } else { if(typeof item.loadedCount == "undefined"){ item.loadedCount = notImagesLoaded.length; notImagesLoaded = item; }; }; }; $(window).addEvent("domready",imagesPreloader);

jQuery 1.3.2 – 1.7.1:

/** delayed image load by Black#FFFFFF **/ loadWait = 30000; loadCheck = 300; preloadObjects = "img"; notImagesLoaded = ; excludeImages = false; function getScreenHeight(){ var myHeight = 0; if(typeof(window.innerHeight) == "number") { //Non-IE myHeight = window.innerHeight; } else if(document.documentElement && (document.documentElement.clientHeight || document.documentElement.clientHeight)){ //IE 6+ in "standards compliant mode" myHeight = document.documentElement.clientHeight; } else if(document.body && (document.body.clientHeight || document.body.clientHeight)) { //IE 4 compatible myHeight = document.body.clientHeight; } return myHeight; } function preloadOther(){ var l = notImagesLoaded.length; var currentExists = false; for(var i = 0; i < l; i ++){ var item = notImagesLoaded[i]; if(item){ loadImage(item); currentExists = true; }; }; if(!currentExists){ notImagesLoaded = ; jQuery(window).unbind("scroll",preloadOther); }; }; function imagesPreloader(){ jQuery(preloadObjects).each(function(){ var item = this; if(item.nodeName.toLowerCase() == "img" && (typeof excludeImages == "undefined" || excludeImages == false || (item.className.indexOf(excludeImages) == -1))){ item.longDesc = item.src; item.src = "#"; item.alt = ""; var preloaderElt= jQuery(""); jQuery(preloaderElt).css({"display":"block"}); preloaderElt.className = "preloader "+item.className; jQuery(item).before(preloaderElt); loadImage(item); }; }); jQuery(window).bind("scroll",preloadOther); }; function loadImage(item){ var pos = jQuery(item).position(); var ItemOffsetTop = typeof pos == "object" && typeof pos.top != "undefined" ? pos.top: 0; var documentScrollTop = jQuery(window).scrollTop(); var scrHeight= getScreenHeight(); if(ItemOffsetTop loadWait){ clearInterval(item.storePeriod); item.storePeriod = false; if(typeof item.loadedCount != "undefined" && notImagesLoaded){ notImagesLoaded = false; }; jQuery(item).css({"display":"none","visibility":"hidden"}); jQuery(item.previousSibling).remove(); }; },loadCheck); } else { if(typeof item.loadedCount == "undefined"){ item.loadedCount = notImagesLoaded.length; notImagesLoaded = item; }; }; }; jQuery(document).ready(imagesPreloader);

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

Примечание: для использования в режиме совместимости с jQuery.noconflict() все вхождения знака $ заменены на передачу параметров объекту jQuery

Настройки javascript:

  • preloadObjects = “img”; – здесь указываем селектор, откуда выбирать изображения? Можно выбрать все изображения на странице “img”, можно выбрать только изображения с определенным классом, например: “img.lazyload”, или в определенном родительском контейнере “#parentcontainer img”.Примечание автора: так как выбор селектора для назначения отложенной загрузки изображений остается за Вами, мы решили добавить маленькую проверочку и выбрать только те элементы с указанными селекторами, которые будут являться изображениями, чтобы избежать конфликтных ситуаций.
  • loadWait = 30000; -максимальное время в миллисекундах, до которого будет проводиться проверка загрузки изображения (эмуляция события image.onload), и после которого изображение будет считаться битым или незагруженным
  • loadCheck = 300; – задержка в миллисекундах между интервалами проверки состояния изображения (загружено или нет?). Равна по умолчанию пол секунды, можно поставить и меньшее значение. Но не советуем Вам выставлять значение меньше 200 миллисекунд, если изображений много, то слишком быстрые интервальные «опросы» приведут к «тормозам» обозревателя.
  • notImagesLoaded = ; – массив будет использоваться для хранения наших изображений
  • excludeImages = false; – для определенных изображений, которые требуется исключить из «отложенной» загрузки, можно назначить дополнительный класс, имя которого назначить параметру excludeImages , например: excludeImages=”exclude”; исключит изображения с классом exlude из процесса «отложенной» загрузки. Делается это для избегания конфликтов с другими типами javascript библиотек, работающими на Вашем сайте над изображениями (только в том случае прибегайте к этому способу, когда конфликт действительно возникает).
  • Настройки css:

    Для стилизации элемента, который отображает загрузку изображения, используется класс

    Span.preloader { display: block; background: url(путь к изображению загрузки); }

    Здесь Вы сможете стилизовать элемент, который будет отображаться «вместо» изображения до полной его загрузки, как Вам будет угодно. А также этому элементу span.preloader будет присвоен дополнительный класс, соответствующий классу изображения, что упростит формирование css стилей.

    Пояснение: это значит, что если у изображения, добавленного в очередь отложенной загрузки, класс class=”bigImage” , то у «заглушки» span.preloader , которая будет «визуализировать» процесс загрузки, соответственно класс class=”preloader bigImage” , по сути, к заглушке будут применяться все те правила, которые будут назначены для изображения. В итоге при отложенной загрузке изображений вид страниц сайта остается неизменным.

    В каких браузерах тестировалась отложенная загрузка?

    IE 7,8,9, Firefox 3.6 – 10, Opera 11.61, Safari, Chrome последние

    Как убедиться в том, что «отложенная загрузка» действительно работает? И загружает изображения точно после загрузки страницы?

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

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

    Будет ли версия отложенной загрузки на чистом javascript без использования jQuery, Mootools?

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

    Сегодня я покажу как сделать ленивую загрузку изображений с помощью плагина B-lazy .

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

    Приступим

    Первым делом скачаем плагин. Для этого перейдем на сайт http://dinbror.dk/blazy/, в правом верхнем углу нажмем« Download». Из открывшейся вкладки скопируем код плагина и вставим его в наш js файл. Если нет желания идти на сайт плагина, скопируйте код из поля ниже.


    // Код библиотеки /*! hey, Lazy.js - v1.8.2 - 2016.10.25 A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy) (c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy */ (function(q,m){"function"===typeof define&&define.amd?define(m):"object"===typeof exports?module.exports=m():q.Blazy=m()})(this,function(){function q(b){var c=b._util;c.elements=E(b.options);c.count=c.elements.length;c.destroyed&&(c.destroyed=!1,b.options.container&&l(b.options.container,function(a){n(a,"scroll",c.validateT)}),n(window,"resize",c.saveViewportOffsetT),n(window,"resize",c.validateT),n(window,"scroll",c.validateT));m(b)}function m(b){for(var c=b._util,a=0;a=c.left&&b.bottom>=c.top&&b.left
    © omutsu.ru, 2024
    Компьютерные подсказки - Оmutsu