Загрузка картинок в фоне. Модуль на JavaScript

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


Проблема:

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

Решение:

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

Загрузка картинок в фоне. JavaScript

Когда нужен скрипт:

  • У вас сложный сайт
  • Подгружаете информацию ajax`ом
  • Много верстки, которая может быть не показана пользователю

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

Как это работает:

  • У вас есть некая скрытая страница с картинками.
  • Вместо них грузиться изображение в 1px.
  • Скрипт пробегает по всем картинкам, разделяя их на группы.
  • Если у вас есть свободное время без нагрузки — вы можете скриптом подгрузить картинки определенной группы (если предполагаете, что скоро они могут понадобиться пользователю).
  • Если пользователь запросил вашу скрытую страницу — вы показываете картинки.
  • Если вы указали неправильный адрес картинки — она просто оставит вашу заглушку в 1px и не будет менять изображение.

Скачать: демо, сам модуль

Преимущества:

Модуль написан на нативном JavaScript.
Для его работы не нужны никакие библиотеки.
Сжат с помощью Google Compressor до 1.5 кб.
Поддерживает паттерн цепочек. То есть методы можно вызывать так:
lazyLoadingImages.show(«1»).load(«2»).load(«3»);
При желание можно пробросить в модуль ссылку на ваш объект или переменную и уйти от создания ещё одной глобальной переменной.

Использование:

В заголовок страницы вставьте:
<script defer src="js/lazyLoadingImages.min.js"></script>

Картинки в документе описывать таким образом:
<img src="./images/empty.png" url="./images/1200.jpg" type="group1" />

Где:

src="./images/empty.png" — адрес картинки заглушки размером в 1px
url="./images/1200.jpg" — адрес оригинальной большой картинки
type=«group1»- ID группы, необязательный параметр

Загрузка картинок в фоне. JavaScript

Интерфейс

По событию DOMContentLoaded (окончание загрузки DOM) глобальному объекту, проброшенному в модуль присваивается метод lazyLoadingImages (по умолчанию это window.lazyLoadingImages).

lazyLoadingImages.update() — обновит список картинок и запомнит их url для загрузки оригинальных изображений. Этот метод вызывается автоматически, при инициализации модуля. Может быть полезен, если DOM страницы изменился.

lazyLoadingImages.load(type) — загрузит картинки определенной группы (параметр type указывает какой именно). Параметр type — необязательный. По умолчанию загружает картинки, которым ID группы не задан.

lazyLoadingImages.show(type) — показать картинки определенной группы (параметр type указывает какой именно). Параметр type — необязательный. По умолчанию показывает картинки, которым ID группы не задан.

UPD:
В связи с тем, что rghost недоступен ссылка на GitHub
MechanisM спасибо за замечание, параметры переименовал. Теперь data-url и data-type.

О картинке заглушке


Когда вставляем картинки в документ (Например, выводим длинный список игроков через innerHTML) можно добавить небольшой трюк:
  • Все картинки вставляем с свойством visibility = hidden (а лучше display: none)
  • Навешиваем событие onload на все картинки
  • Если onload произошёл — убираем visibility, если нет — оставляем как есть


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

CSS
.visibility {
    visibility: hidden;
}


JavaScript
utils.showAfterLoading: function(node) {
	utils.removeClass(node, "visibility");
}


HTML
<img src="битый url" class="visibility" onload="utils.showAfterLoading(this)" />


UPD2:

Добавил два метода согласно замечаниям DjOnline:

lazyLoadingImages.onScroll(type) — показать картинки определенной группы (необязательный параметр type указывает какой именно) при прокрутке страницы (а именно начать подгрузку изображения, когда до него останется «пол экрана»). По умолчанию показывает картинки, которым ID группы не задан.

lazyLoadingImages.offScroll(type) — отменяет показ картинки определенной группы (необязательный параметр type указывает какой именно) при прокрутке страницы (см. метод выше). По умолчанию сбрасывает onScroll картинкам, которым ID группы не задан.

Так что теперь модуль может догружать картинки при прокрутке. Вес: 2.7 kb

Демо: тут или тут

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 17

    +12
    <img src="./images/empty.png" url="./images/1200.jpg" type="group1" />
    

    Может лучше все-же сделать «data-url» и «data-type»?
    Насчет демо и кода — лучшеб залили код на гитхаб а демо на jsfiddle например. Лично у меня не грузится rghost(ну и я не видел ни кода ни демо).
      0
      Интересный подход с подстановкой картинок-заглушек. Сам когда-то сталкивался с подобной проблемой и писал велосипед, но о заглушках не подумал.
      Поддерживаю MechanisM и жду код на github )
        0
        Демо можно запускать прямо с github — htmlpreview.github.com/?https://github.com/bakhirev/lazyLoadingImages/blob/master/demo.html
        Предзагрузки при скролле страницы нет?
          0
          Нет, нету. Но идея очень понравилась, добавлю в следующий коммит. Спасибо!
          0
          1) Не нравится что атрибут src получается, как я понял, заглушкой в коде страницы (может быть плохо для индексации)
          2) Есть же такой скрипт thinkpixellab.com/pxloader/
            0
            1. Да плохо, но решение пока не нашел. На работе посоветовали на лету делать подмену на адрес заглушки, но на практике — оказалась лажа. Браузер все равно успевал начать загрузку большого изображения.
            2. Насколько я понял — он в canvas рисует ->
            а. Нет поддержки в старых браузерах
            б. Делает верстку менее очевидной. Больше смахивает на плагин для создания слайдеров.
            0
            Демо лучше в онлайн выложить, а не архивом
              0
              Да, мой косяк, но ссылка написанная DjOnline (htmlpreview.github.com/?https://github.com/bakhirev/lazyLoadingImages/blob/master/demo.html) очень хорошо показывает суть модуля, т.к. картинки по ней грузятся очень долго. Используй её.
              0
              Лицензия?
                0
                и вычислять изображения «за сгибом» страницы не планируется?
                  0
                  Поясни «вычислять изображения «за сгибом» страницы»? в плане, когда пользователь собирается переключить видимую вкладку?
                    0
                    в плане — скрывать только невидимые изображения, а видимые показывать
                +1
                // worse
                global = ((global) ? global : window);
                
                
                // better
                global = global || window;
                
                  0
                  Спасибо! Поправил. Буду очень благодарен за код ревью, если не лень конечно.
                  0
                  я дико извиняюсь, но зачем, когда есть www.appelsiini.net/projects/lazyload

                  и зачем src="./images/empty.png" когда есть src=«data:image/gif;base64,....»,
                  а еще проще src=«data:null»
                    0
                    1.
                    > Lazy Load Plugin for jQuery.
                    > jQuery
                    Решение для тех, кто по какой-либо причине должен отказаться от jQuery или вообще от сторонних библиотек (он весит столько же как и этот плагин, только 90kb jQuery уже не нужны).

                    2. src=«data:null» — не проще, ибо появляется значок image
                    0
                    ладно, тогда так data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

                    Only users with full accounts can post comments. Log in, please.