Автоматизация адаптивных изображений с помощью Mobify.js.

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

Наблюдается следующая тенденция: только за прошлый год средний размер страниц увеличился с 1 мегабайта до ошеломляющих 1,5 мегабайт. Более 60% этого роста приходится на изображения и этот процентный показатель только увеличивается.

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

В идеальном случае можно было бы воспользоваться тегом img и браузер выполнял бы скачивание именно тех объектов, которые необходимы в зависимости от ширины дисплея устройства и шаблона страницы. Однако никакой подобной функции в настоящее время не существует. Один из способов получить нечто напоминающее подобную функцию, заключается в мгновенном изменении src атрибута в img элементе с помощью JavaScript. Синтаксический анализатор предостерегает от использования подобной опции.

Первый шаг к решению существующей проблемы заключается в создании специальной разметки, которая позволяет использовать альтернативные источники изображений. В зависимости от возможностей устройства будет загружаться подходящее по размеру изображение. Подобная возможность была получена благодаря созданию picture элемента, разработанного W3C (консорциум World-Wide Web) Сообществом по продвижению адаптивных изображений (хотя ни один браузер в настоящее время в своем оригинальном виде не реализует эту функцию).

Тем не менее, при использовании picture элемента возникает совершенно новая проблема: теперь разработчики должны создавать отдельные активы для каждого изображения в каждой точке прерываний. В действительности разработчикам необходимо решение, которое позволяет автоматически генерировать небольшие изображения для устройств с малым дисплеем из изображений с высоким разрешением. В идеале, это автоматизированное решение будет совершать только один запрос на изображение, будет 100% семантическим и обратно совместимым. Функция Image API в Mobify.js предусматривает подобное решение.

Элемент < picture>, как проявление наиболее передовой практики.

Элемент picture в настоящее время является наиболее вероятным претендентом на замену img элемента, поскольку он позволяет разработчикам устанавливать различные версии изображений для различных разрешений экрана. Подобная возможность может помочь решить проблему производительности и графического отображения (также более детального изучения заслуживает новое SrcN предложение). Типичная установка включает в себя определение точек прерывания, генерацию изображений для каждой контрольной точки, а затем написание picture разметки для изображения. Давайте посмотрим на то, как можно получить адаптивное изображение с помощью рабочего потока, который включает элемент picture:

President Obama and Governor Christi

Мы будем использовать базовую линию на отметках 320, 512, 1024 и 2048 пикселей.

Во-первых, мы должны создать копии изображения для каждого вида разрешения. Это можно сделать либо с помощью любого интерфейсного инструмента с командной строкой (CLI), например Image Optim, или путем использования команды «Save for web» (сохранить для интернета) в Photoshop. Затем воспользуемся следующей разметкой:

<picture>
    <source src="responsive-obama-320.png">
    <source src="responsive-obama-512.png" media="(min-width: 512px)">
    <source src="responsive-obama-1024.png" media="(min-width: 1024px)">
    <source src="responsive-obama-2048.png" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-320.png"></noscript>
</picture>

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

President Obama and Governor Christi

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

responsive-obama-mobile

Поскольку этот файл является не просто уменьшенной версией оригинала, имя файла должно содержать другую структуру (responsive-obama-mobile.png вместо responsive-obama-320.png):

<picture>
    <source src="responsive-obama-mobile.png">
    <source src="responsive-obama-512.png" media="(min-width: 512px)">
    <source src="responsive-obama-1024.png" media="(min-width: 1024px)">
    <source src="responsive-obama-2048.png" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-512.png"></noscript>
</picture>

А что, если мы захотим использовать устройства с высоким DPI (количество точек на дюйм)? Спецификация элемента picture содержит srcset атрибут, который позволяет легко устанавливать различные виды изображений для различных пиксельных соотношений. Ниже представлен пример разметки, в которой используется picture элемент.

<picture>
    <source srcset="responsive-obama-mobile.png 1x, responsive-obama-mobile-2x.png 2x">
    <source srcset="responsive-obama-512.png 1x, responsive-obama-1024.png 2x" media="(min-width: 512px)">
    <source srcset="responsive-obama-1024.png 1x, responsive-obama-1024.png 2x" media="(min-width: 1024px)">
    <source srcset="responsive-obama-2048.png 1x, responsive-obama-4096.png 2x" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-512.png"></noscript>
</picture>

Мы ввели несколько новых файлов (responsive-obama-mobile-2x.png и responsive-obama-4096.png), которые также должны быть загружены. На данный момент, у нас будет шесть различных копий одного изображения.

Давайте сделаем еще один шаг вперед. Что делать, если мы условно хотим загрузить наши изображения в более современном формате, например WebP, в зависимости от того поддерживает ли браузер данный формат или нет? Внезапно, общее количество файлов, которые мы должны генерировать увеличивается с 6 до 12. Давайте будем честными: никто не захочет создавать несколько версий с различными разрешениями для каждого изображения и постоянно обновлять эти версии в разметке. Нам нужен автоматизированный процесс!

Идеальный рабочий поток адаптивного изображения.

Идеальный рабочий процесс – это процесс, который позволяет разработчикам загружать изображения в максимально возможном разрешении, при этом используя img элемент таким образом, чтобы он автоматически изменял размер и сжимал изображения для различных браузеров. Использовать элемент img очень удобно, поскольку это простой тег для решения простой задачи: отображение изображений для пользователей в интернете. Дальнейшее использование этого элемента для решения проблем производительности и обратной совместимости было бы идеальным вариантом. Затем, когда возникает потребность в художественной обработке и масштабировании изображения, мы могли бы использовать picture элемент; логика ветвления встроенная в его синтаксис, идеально подходит для использования выборки.

Идеальный рабочий поток можно создать с помощью адаптивного Image API в Mobify.js. Mobify.js – это открытая библиотека, которая позволяет улучшить адаптивный веб-сайт, создавать адаптивные изображения, выполнять JavaScript и CSS оптимизацию, создавать адаптивные шаблоны и многое другое. Image API автоматически изменяет размер и сжимает img и picture элементы и, при необходимости, делает это, не меняя ни одной строки разметки в бэк-энде. Просто загрузите изображения с высоким разрешением и пусть API выполняет всю работу.

Автоматическое создание адаптивных изображений без изменения бэк-энда.

Проблему адаптивных изображений трудно решить из-за синтаксического анализатора, который мешает нам изменять src атрибут img элемента с помощью JavaScript. Синтаксический анализатор является особенностью браузеров. Он инициализирует загрузку ресурсов, порождая отдельный поток за пределами основного потока визуализации, и чьей единственной целью является нахождение расположения ресурсов и их параллельное скачивание. Принцип работы синтаксического анализатора учитывает основные требования адаптивного дизайна. В нашем мире, полном разнообразных устройств, изображения в разметке – это не обязательно те изображения, которые должны загружаться пользователем. Таким образом, мы должны задуматься над созданием таких программных интерфейсов, которые позволяют разработчикам контролировать загрузку ресурсов без ущерба синтаксическому анализатору. Для получения дополнительной информации по этой теме, не поленитесь прочитать публикацию Стива Соудерса «Я <3 байты изображения».

Многие разработчики прибегают к хитростям чтобы избежать действия синтаксического анализатора. Они вручную устанавливают src атрибут каждого img в data-src, результатом чего становится игнорирование синтаксическим анализатором этих изображений. Затем производится изменение data-src назад до src с помощью JavaScript. С помощью Capturing API (сбор) в Mobify.js, мы можем полностью отказаться от использования подобного подхода, что позволяет сохранять производительность, и создать полностью семантическое представление (отсутствуют такие хэки как <noscript> или data-src). Метод сбора ограничивает синтаксический анализатор от предварительной загрузки ресурсов на странице, но это вовсе не означает, что будут остановлены параллельные загрузки. Использование Image API в Mobify.js в сочетании с методом сбора, позволяет создавать адаптивные изображения при помощи только одного JavaScript тэга.

Вызов API выглядит следующим образом:

Mobify.Capture.init(function(capture){
    var capturedDoc = capture.capturedDoc;
    var images = capturedDoc.querySelectorAll('img, picture');
    Mobify.ResizeImages.resize(images, capturedDoc) 
    capture.renderCapturedDoc();
});

Вы можете взять любое изображение на странице и переписать src по следующей схеме:

http://ir0.mobify.com/<format><quality>/<maximum width>/<maximum height>/<url>

Например, если этот API был запущен в последней версии Chrome для Android на устройстве с шириной экрана 320 CSS пикселей и пиксельным соотношением устройства равным 2, то следующее изображение…

<img src='cdn.mobify.com/mobifyjs/examples/assets/images/forest.jpg'>

… будет переписан так:

<img src='//ir0.mobify.com/webp/640/http://cdn.mobify.com/mobifyjs/examples/assets/images/forest.jpg'>

Изображение будет изменено до 640 пикселей в ширину, а так как Chrome поддерживает формат WebP, мы хотели бы воспользоваться этой возможностью, чтобы еще больше уменьшить размер изображения. После первого запроса изображение будет кэшироваться CDN (сеть доставки контента) в Mobify, а в следующий раз это будет необходимо только для конкретного размера и формата. Поскольку это изображение не требует художественной обработки, мы можем продолжать использовать img элемент.

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

Используя данное решение, мы с лёгкостью можем организовать собственный рабочий поток. От нас всего лишь требуется загрузить версию с высоким разрешением для каждого изображения, а API будет выполнять всю дальнейшую работу по автоматическому изменению их размера. Не стоит использовать модуль доступа и не нужно выполнять изменение каких-либо атрибутов — достаточно всего одной строки JavaScript кода, которую нужно скопировать на сайте. Давайте двигаться дальше и попробуем скопировать и вставить следующую строку кода в верхней части вашего head элемента (обратите внимание, что эта строка должна размещаться раньше любого другого тега, который загружает внешний ресурс).

<script>!function(a,b,c,d,e){function g(a,c,d,e){var f=b.getElementsByTagName("script")[0];a.src=e,a.id=c,a.setAttribute("class",d),f.parentNode.insertBefore(a,f)}a.Mobify={points:[+new Date]};var f=/((; )|#|&|^)mobify=(\d)/.exec(location.hash+"; "+b.cookie);if(f&&f[3]){if(!+f[3])return}else if(!c())return;b.write('<plaintext style="display:none">'),setTimeout(function(){var c=a.Mobify=a.Mobify||{};c.capturing=!0;var f=b.createElement("script"),h="mobify",i=function(){var c=new Date;c.setTime(c.getTime()+3e5),b.cookie="mobify=0; expires="+c.toGMTString()+"; path=/",a.location=a.location.href};f.onload=function(){if(e)if("string"==typeof e){var c=b.createElement("script");c.onerror=i,g(c,"main-executable",h,mainUrl)}else a.Mobify.mainExecutable=e.toString(),e()},f.onerror=i,g(f,"mobify-js",h,d)})}(window,document,function(){var a=/webkit|msie\s10|(firefox)[\/\s](\d+)|(opera)[\s\S]*version[\/\s](\d+)|3ds/i.exec(navigator.userAgent);return a?a[1]&&+a[2]<4?!1:a[3]&&+a[4]<11?!1:!0:!1},

// path to mobify.js
"//cdn.mobify.com/mobifyjs/build/mobify-2.0.0.min.js",

// calls to APIs go here
function() {
  var capturing = window.Mobify && window.Mobify.capturing || false;

  if (capturing) {
    Mobify.Capture.init(function(capture){
      var capturedDoc = capture.capturedDoc;

      var images = capturedDoc.querySelectorAll("img, picture");
      Mobify.ResizeImages.resize(images);

      // Render source DOM to document
      capture.renderCapturedDoc();
    });
  }
});
</script>

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

Вы также можете использовать полную документацию. Поддержка браузерами фрагмента кода, представленного выше, выглядит следующим образом: все Webkit/Blink ориентированные браузеры, Firefox 4+, Opera 11+, и Internet Explorer 10+.

Автоматическое изменение размера img элементов отлично подходит для большинства вариантов использования. Но, как показано в примере с изображением Обамы, для определенных типов изображений необходима художественная обработка. Как же мы можем использовать picture элемент для художественной обработки без необходимости создавать шесть версий одного и того же изображения? Инструмент Image API будет изменять размер picture элементов. Это означает, что вы можете использовать picture элемент по своему непосредственному назначению (художественная обработка), а процедуру изменения размеров оставить для API.

Изменение размера <picture> элементов.

Можно автоматическ …

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.