Pull to refresh

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

Reading time 4 min
Views 9.2K
Некоторое время назад я начал писать большой проект с высокой нагрузкой, в котором широко использовались возможности 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

Демо: тут или тут
Tags:
Hubs:
+25
Comments 17
Comments Comments 17

Articles