Frontender Magazine

Выбираем решение для изображений в отзывчивом дизайне

Шерри Александр

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

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

Принципы

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

img {
    max-width: 100%;
}

В большинстве случаев этого достаточно. Когда такое правило есть в таблице стилей, то, если контейнер изображения станет уже ширины изображения, то изображение уменьшится в масштабе, чтобы соответствовать ширине контейнера. Установка max-width на 100% также гарантирует, что изображение не будет увеличиваться больше своего реального размера и качество картинки не пострадает. Если вам все еще приходится поддерживать IE6/7, то для них придется добавить правило width: 100%, поскольку max-width они не поддерживают.

Это базовое решение усложняется, если вам нужно принимать в расчет retina-изображения с большим разрешением. Например, вы хотите, чтобы ваш логотип размером 150х150 пикселей показывался на удвоенном разрешении, и картинка достаточно маленькая, так что иметь две разные версии — не проблема. Итак, вы делаете версию логотипа размером 300х300 и подключаете ее: он стал огромным! Ваш первый позыв, вероятно, попробовать что-то такое в CSS:

img.sitelogo {
    max-width: 150px;
}

К сожалению, это не работает как надо — изображение логотипа больше не будет масштабироваться вместе с другими изображениями на странице. Для того, чтобы ограничить максимальную ширину адаптивного изображения, нужно ограничить максимальную ширину контейнера изображения, а не самого изображения. Скажем, ваш логотип находится внутри элемента, у которого стоит класс branding. В таком случае вот тот код, который вам нужен:

.branding {
    max-width: 150px;
}

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

Не так быстро! У нас есть еще две проблемы, которые нужно преодолеть.

Проблема с производительностью

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

Подумайте об этом. Действительно ли мы должны посылать на мобильный телефон 100-килобайтовую картинку размером 990х300 пикселей, предназначенную для десктопа. Конечно, посетитель может использовать wifi-соединение из местной кофейни — но может быть, что он где-то в дороге, индикация приема сети упала до одной полоски, а он пытается найти на вашем сайте ключевую информацию. Каждый мобильный пользователь, который уходит со страницы, потому что она грузится слишком долго — это потенциальный потерянный клиент.

На бескрайних просторах интернета можно найти большое количество мобильных сайтов, которые такие же по размеру или даже больше, чем их десктопные версии. Гай Подъярный провел несколько замеров с разницей в год, и не сказать, чтобы ситуация улучшалась: в 2011 86% мобильных сайтов были такого же размера или больше, а в 2012 эта цифра уменьшилась до 72%, но средний вес сайта увеличился. Дэйв Руперт очень тонко обозначил проблему в своей статье "Больше пикселей — больше проблем".

Еще одна сложность: предварительная загрузка в браузерах

Когда я впервые начал бороться с проблемами производительности на отзывчивых сайтах, моя первая идея была такая: поставить все варианты картинок на странице, а потом настроить классы с медиа-запросами в CSS, которые скрывали бы большие изображения и показывали маленькие на малом разрешении, и наоборот — на большом. Все казалось логично: браузер ведь должен загружать только видимые изображения, не правда ли?

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

Из-за предзагрузки большинству нужно либо решение на бэк-энде (чтобы опередить предзагрузку) — или специальная разметка и JavaScript.

Определение пропускной способности

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

W3C работает над Network Information API, которая в будущем может очень пригодиться, но на данный момент поддерживается только очень ограниченным набором устройств (и никем из популярных). В нескольких решениях для отзывчивых картинок эта API уже используется, но я не думаю, что ее будут широко применять до того, как большее количество устройств начнет его поддерживать. Измерять скорость работы сети сложно, и, как отмечает Йоав Вайс в своей статье в Smashing Magazine, надежные «медиа-запросы для пропускной способности сети» вряд ли можно будет точно реализовать в ближайшем будущем.

Foresight.js Адама Брэдли использует JavaScript для того, чтобы протестировать, сколько браузер будет загружать картинку в 50 КБ, и потом сохраняет эту информацию для того, чтобы вы могли принимать решения относительно пропускной способности сети. Но у этого подхода есть несколько маленьких недостатков: к весу страницы прибавляется 50 кб, и библиотека блокирует загрузку остальных изображений, пока не скачается тестовое. Многие из решений для отзывчивых изображений, которые включают определение пропускной способности сети, используют Foresight.js или похожие приемы.

Проблема контекста

Скажем, у вас на домашней страничке есть большая красивая картинка. На ней — поля и леса, голубое небо, пушистые облака, и счастливая семья устраивает пикник на траве.

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

Tree

Когда большое изображение уменьшается, детали теряются. (Иллюстрация: Марк Макквитти)

Такую проблему мы называем проблемой «контроля впечатления». Некоторые изображения просто не могут хорошо масштабироваться: тонкие детали теряются, изменяется то впечатление, которое оно производит. В случае нашего изображения, было бы гораздо лучше, чтобы на мобильной версии изображения фотография была бы увеличена, обрезана так, чтобы поместить в центр изображения нашу счастливую семью. Для того, чтобы решить эту проблему, нам нужно решение для отзывчивых изображений, которое позволяет либо задать разные версии изображения для разных ситуаций — либо изменять изображение на лету.

Tree

Иногда для узких изображений нужен другой масштаб и обрезка. (Иллюстрация: Марк Макквитти)

Выбираем решение

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

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

Вот несколько факторов, которые нужно иметь в виду:

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

Обратите внимание: список этих решений далеко не полон. В этот список входят либо те, которые я лично считаю самыми полезными, либо те, которые известны своей надежностью. У вас есть ваше любимое решение, которого нет в списке? Напишите о нем в комментариях!

Проверенные опытом решения для реализации отзывчивых изображений

PICTUREFILL

Веб — действительно всемирная паутина, и нужно принимать во внимание тот факт, что не у каждого пользователя есть доступ к оптоволоконному соединению и 4G-сетям. Скотт Джел столкнулся с этим цифровым разделением лицом к лицу, когда путешествовал и работал в Юго-Восточной Азии, и он очень серьезно отстаивает подход «сперва мобильная версия» и выступает за отзывчивые сайты, которые не кладут на мобильных пользователей неподъемную ношу. Его скрипт Picturefill — полифилл для предложенного в будущей спецификации HTML элемента <picture> — это JavaScript-код, который повторяет API элемента picture, позволяя нам, таким образом, использовать этот элемент на сайтах уже сейчас. Будущее наступило, детка!

Picturefill

Для Picturefill не требуется jQuery, но, естественно, нужно, чтобы где-то на странице включался скрипт picturefill.js. Picturefill, кроме того, требует специальной разметки, в которой дивы представляют собой варианты изображений, отличающиеся атрибутом data-media, который работает так же, как медиа-запросы в CSS. Еще можно опционально поместить изображение в условный комментарий — для браузеров, которые не поддерживают медиа-запросы (IE8, обращаюсь к тебе), и запасной план — тэг <noscript> для браузеров, в которых не включен JavaScript (BlackBerry, обращаюсь к тебе).

Вот пример типичной настройки Picturefill:

<span data-picture data-alt="Descriptive alt tag">
    <span data-src="images/myimage_sm.jpg"></span>
    <span data-src="images/myimage_lg.jpg" data-media="(min-width: 600px)"></span>

    <!--[if (lt IE 10) & (!IEMobile)]>
        <span data-src="images/myimage_sm.jpg"></span>
    <![endif]-->

    <!-- Запасной план для браузеров без JS. -->
    <noscript>
        <img src="images/myimage_sm.jpg" alt="Descriptive alt tag" />
    </noscript>
</span>

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

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

HISRC

HiSRC, написанный Марком Грабански и Кристофером Шмиттом — плагин для jQuery, который позволяет вам создавать версии изображения с низким, средним и высоким разрешением — а скрипт загрузит соответствующее изображение, исходя из готовности устройства отображать ретина-изображения и скорости сети.

HISRC

Чтобы установить его, для начала убедитесь, что на странице подключены jQuery и собственно скрипт HiSRC.

В HTML сперва добавьте обычный тэг изображения, и в качестве его источника установите версию изображения с маленьким разрешением (или самую маленькую). Добавьте к картинке или ее контейнеру класс (например, .hisrc), чтобы указать, какие изображения скрипту следует обработать. Потом добавьте к тэгу картинки специальную разметку: атрибуты data-1x и data-2x, которые указывают соответственно на версии изображения со средним и высоким разрешением. Например:

<img    src="http://placekitten.com/200/100"
        data-1x="http://placekitten.com/400/200"
        data-2x="http://placekitten.com/800/400" class="hisrc" />

Затем, после того как загрузился DOM, просто вызовите функцию с тем классом, который вы использовали для изображений, вот так:

$(document).ready(function(){
   $(".hisrc").hisrc();
});

На практике дело выглядит так. Сперва браузер загрузит источник изображения — то есть мобильную версию картинки. Затем скрипт проверит, не использует ли посетитель мобильное соединение (например, 3G). Если да, то первая картинка остается на месте. Если соединение быстрое, а браузер поддерживает Retina-изображения, тогда выдается версия @2x. Если соединение быстрое, но ретина не поддерживается, тогда выдается версия @1x.

Вы, наверное, заметили, что изображение с низким разрешением грузится в любом случае, даже если скрипт решает, что устройство пользователя вполне подходит для отображения изображения с большим разрешением. Хотя технически это двойная загрузка, проблемы это создает только тем, кто находится на быстрых соединениях. По-моему, вполне приемлемый компромисс! HiSRC может обрабатывать картинки, которые добавляются на страницу динамически. Также он позволяет указывать несколько картинок, стало быть, вы можете определить разные варианты обрезки изображения и решить проблему «контроля впечатления».

У HiSRC есть и недостатки: для его работы требуется jQuery, так что его имеет смысл применять только в тех случаях, если вы уже используете эту библиотеку. Также он требует специальной разметки в HTML, так что, возможно, это не лучший выбор, если у вас есть огромный сайт с большим количеством архивированных картинок или CMS, в которой нельзя переключить вывод тэга изображения. Если это ваш случай, читайте дальше!

Adaptive Images

В отличие от двух предыдущих скриптов Adaptive Images за авторством Мэтта Уилкокса — в основном решение на стороне сервера. Ему требуется чуть-чуть JavaScript, но основную работу выполняет веб-сервер Apache 2, PHP 5.x и библиотека GD.

Чтобы установить это решение на ваш веб-сервер, вам понадобится добавить файл .htaccess, загрузить несколько PHP-файлов в корневой каталог вашего сайта, добавить немножко JavaScript на страницы (чтобы сохранить куки, в котором будет записано разрешение экрана пользователя) и настроить в PHP несколько переменных, чтобы они соответствовали медиа-запросам вашего сайта.

Adaptive Images

Инструкция по установке Adaptive Images довольно объемная и мы не будем на ней останавливаться. Если хотите узнать об этом больше, зайдите на официальный сайт и нажмите на ссылку «Детали» наверху.

Основное достоинство Adaptive Images в том, что он не требует никакой специальной разметки на страницах. После того, как вы установили его и правильно настроили, больше ничего не надо делать. PHP-скрипт будет перехватывать запросы к картинке и форматировать ее на лету согласно той конфигурации, которую вы напишете, и будет отдавать их на страницы автоматически. В скрипте есть много настраиваемых опций, как-то: качество картинки, ключевые точки, кэширование и даже фильтр резкости, который можно применять к сгенерированным картинкам.

У этого скрипта есть несколько ограничений:

Вы, вероятно, заметили, что все решения до сих требовали JavaScript, а некоторые еще и достаточно серьезной настройки. Если вы ищете такое решение, для которого не требуется JavaScript и которое одновременно достаточно простое во внедрении, обратите внимание на Sencha.io Src.

Sencha.io Src

Ранее известный как TinySrc, Sencha.io Src — решение на стороннем сервере, которое работает как прокси-сервер для изображений, так что вам не нужно ничего настраивать на своем сервере. Просто перенаправьте свое изображение на сервера Sencha (с опциями или без них), Sencha обработает его и отправит обратно версию с другими размерами.

SenchaIO

Предположим, у вас есть большое изображение:

<img src="http://www.your-domain.com/path/to/image.jpg" alt="My large image"/>

Самый простой вариант: вы просто ставите перед значением атрибута src http://src.sencha.io/, вот так:

<img src="http://src.sencha.io/http://www.your-domain.com/path/to/image.jpg"

alt="My large image" />

По умолчанию Sencha.io изменит размер вашего изображения, чтобы оно соответствовало ширине экрана устройства, которое Sencha.io определит по строке user-agent. Телефонам отправится изображение на 320 пикселей в ширину, планшетам — 768 пикселей в ширину и т.п.

Вы можете настроить строку префикса Sencha.io, чтобы вам возвращались изображение с конкретным разрешением, ориентацией, размером в процентах — можно использовать самые сложные вычисления. Sencha.io - бесплатный сервис для индивидуальных пользователей и может быть очень удобным решением для адаптивных изображений. Однако вы добавляете зависимость от стороннего сервиса, который всегда может зависнуть, и у которого могут быть проблемы, которые вы никак не можете контролировать. Тщательно взвесьте риски.

Решения для реализации отзывчивых изображений, на которые стоит обратить внимание

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

Capturing/Mobify.js 2.0

Capturing - это новая фича разрабатывающейся ветки Mobify.js 2.0, которая предлагает давать вам доступ к HTML-разметке до того, как браузер распарсит и отобразит ее. Возможность получить доступ к исходному коду на этой стадии дает вам возможность заменить атрибут src изображения до того, как браузер начнет скачивать его. Можно даже сделать запасной режим с одним из других решений (например, Picturefill) — на случай, если что-нибудь упадет.

Mobify

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

Другой момент, которые удерживает меня от того, чтобы начать пользоваться этим решением — это уровень его кроссбраузерной поддержки. Capturing не будет работать в IE ниже 10 версии — так что пользователи IE8 и IE9 остаются в стороне. Я буду следить за этим решением, может быть, потом, когда IE8 и 9 плавно уйдут на свалку истории, это решение будет более применимым.

Если вам интересно узнать больше о Capturing, то команда Mozilla детально рассматривает этот проект в посте: “Capturing: Improving Performance of the Adaptive Web.”

ReSRC.it

ReSRC.it — еще одно стороннее решение (недавно вышло из беты), которое формирует в облаке отзывчивые изображения. По архитектуре оно выглядит очень похоже на Sencha.io Src, но в ReSRC добавляются фильтры изображений, определение пропускной способности канала — и для этого ему не нужно определять браузер по user-agent и хранить данные в куки.

ReSRC

Чтобы начать, сперва нужно зарегистрировать trial-аккаунт на ReSrc.it.

Затем нужно вставить на свою страницу JavaScript-файл (простой JS-код, кроме того, есть и асинхронный метод вставки этого кода на страницу, что увеличивает производительность):

<script src="//use.resrc.it"></script>

Теперь предположим, что у вас есть такое изображение:

<img src="http://path/to/image.jpg" alt="My large image" />

Вы ставите к адресу источника изображения в качестве префикса путь к серверам ReSRC.it и добавляете к изображению CSS-класс resrc (сейчас у них два сервера, один для платных аккаунтов, второй — для бесплатных, и его мы будем использовать в примере):

<img src="http://trial.resrc.it/http://www.your-domain.com/path/to/image.jpg" alt="My large image" class="resrc" />

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

Вот пример изображения, которое горизонтально отражается, масштабируется на 300 пикселей по ширине и картинка оптимизируется в JPEG на качестве в 80%:

<img src="http://trial.resrc.it/r=h/s=w300/o=80/http://www.your-site.co/image.jpg" alt="My large image" class="resrc" />

ReSRC.it недавно вышел из беты, так что если у кого-то есть советы по использованию этого сервиса или мнение о нем (плюсы/минусы), мы с радостью прочитали бы их в комментариях.

Тестируйте, тестируйте, тестируйте!

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

YSlow

Разработанное Yahoo, YSlow — инструмент на клиенте, который анализирует ваш сайт по 23 признакам, которые, по мнению Yahoo, могут отрицательно сказываться на производительности веб-страницы. YSlow присваивает вашему сайту оценку по каждому правилу, объясняет каждое и предлагает вам, как улучшить производительность сайта. YSlow доступен для Firefox, Chrome, Safari и Opera (ну и еще несколькими способами, например, из командной строки).

WebPageTest

Онлайн-инструмент WebPageTest — опенсорс-проект, поддерживающийся Google. Вы вводите URL вашего сайта, проводите тест на скорость из выбранного место и определяете, какой браузер использовать. Дополнительные настройки позволяют вам выбрать набор действий из нескольких шагов, выбрать скорость сети (ADSL/оптоволокно и пр.), отключить JavaScript, блокировать рекламу и делать другие запросы, и так далее. Результате приходят в виде таблиц, графиков, скриншотов, обзора производительностью и большого количества данных, в которых можно покопаться.

В блоге Yottaa есть статья, в которой подробно рассказывается, как они использовали WebPageTest для тестирования сайта с отзывчивыми изображениями и без — почитайте!

В заключение

Если вы читаете Smashing Magazine, скорее всего, вы уже пытаетесь создать самые лучшие условия из всех возможных для восприятия вашего сайта его аудиторией. Так что в следующий раз, когда вы будете создавать что-то красивое и полезное для мобильных пользователей, попробуйте одно из этих решений для отзывчивых изображений и сделайте свой сайт еще лучше. Пользователи на мобильных устройствах скажут вам спасибо!

Хотите копнуть глубже?

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Sherri Alexander
Vlad Andersen

Комментарии (2 комментария, если быть точным)

Автар пользователя
Safe-Mode

Я так понимаю, статья неактуальна уже?

Автар пользователя
vladoska

Так же так думаю, можно использовать picture, srcset, и полифил для поддержки динозаврами