Исследуем проблемы производительности адаптивных изображений

Адаптивные изображения

От автора: В магазинах продаются пятидюймовые мобильные устройства с тем же разрешением экрана, что у 50-дюймовых телевизоров. У нас есть пользователи с неограниченной высокоскоростной широкополосной сетью, и есть пользователи, оплачивающие каждый переданный мегабайт. Адаптивный дизайн изображений означает оптимизацию процесса их доставки к пользователям. В настоящей статье мы поделимся своей методикой адаптивных изображений — “padding-bottom”, которую мы изучили и применили в мобильной версии шведского новостного вебсайта Aftonbladet.

Представленные здесь методы являются результатом нескольких недель исследований, предпринятых нами в октябре 2012г. Нам посчастливилось стать частью команды, создававшей для Aftonbladet новый адаптивный мобильный вебсайт. Aftonbladet – это самый большой шведский сайт, и у его мобильной версии примерно 3 миллиона пользователей и до 100 миллионов просмотров в неделю.

Учитывая такое количество пользователей, мы сочли своим долгом создать быстрый и хорошо оптимизированный вебсайт. Экономия всего 100 KB изобразительных данных при просмотре страницы вылилась бы в терабайты трафика, сэкономленных в Швеции за год. Мы начали с изучения других техник адаптивных изображений, но так как ни одна из них не подходила нам идеально, то в итоге мы скомбинировали несколько лучших хаков в свое собственное решение. Пожалуйста, обратите внимание, что проект касался только мобильного адаптивного вебсайта; но не беспокойтесь — представленная здесь методика применима ко всем видам адаптивных вебсайтов.

Спецификация

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

легко кэшироваться,

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

Давайте пройдемся по этим требованиям и рассмотрим, что они означают.

ЛЕГКОЕ КЭШИРОВАНИЕ

Имея вебсайт, пики трафика которого насчитывают более 10 000 запросов в секунду, нам хотелось сохранить серверную логику насколько можно простой. Это означает, что нам требовалась детекция устройств на серверной стороне или решение на основе куки, поставляющее множественные версии HTML. Нам хотелось доставлять всем пользователям единственный файл HTML, хотя было приемлемо манипулирование HTML с помощью JavaScript’а после его загрузки. Те же правила применялись к изображениям; нужна была возможность выкладывать изображения в сеть доставки контента (CDN), а в логике доставки изображений не нужно было никакой динамики.

МУЛЬТИДОСТАВКА ИЗОБРАЖЕНИЙ

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

Загрузка изображений с помощью JavaScript’а

JavaScript, будучи помещенным в нижний колонтитул, где ему самое место, будет загружаться после анализа HTML и CSS. Это означает, что если JavaScript несет ответственность за загрузку изображений, то мы не можем пользоваться преимуществом браузерного средства предварительной загрузки, и поэтому изображение начнет загружаться гораздо позже обычного. Конечно, это нехорошо, и при этом обнажается другая проблема: страница может перерисовываться каждый раз при вставке JavaScript’ом изображения в DOM.

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

Как видно из видеоролика, еще очень раздражает то, что пользователь наверняка потеряется в перерисовке при возврате на страницу при помощи кнопки «Назад» (“Back”). Это действительно серьезная проблема для таких вебсайтов, как Aftonbladet. Наличие функциональной кнопки «Назад» удержит пользователей на вебсайте на более длительное время.
На самом деле проблемы перерисовки не будет на неадаптивном вебсайте, потому что мы сможем установить к тэгу изображения ширину и высоту в пикселях:

<img src="img.jpg" width="60" height="60"/>

Одним из важных аспектов адаптивного вебдизайна является удаление таких жестко запрограммированных атрибутов и создание гибких изображений с помощью CSS:

img {
	max-width: 100%;
}

Нет больше max-width: 100%

Нам нужно было отыскать решение, посредством которого мы могли бы приберечь место для изображения с помощью одного HTML и CSS и, таким образом, избежать повторной заливки. То есть, когда JavaScript вставляет изображение на страницу, оно будет вставлена только в предназначенную область, а мы избежим перезаливки. Итак, мы отбросили один из угловых камней адаптивного дизайна, img { max-width: 100% }, и стали искать другое решение, которое могло бы резервировать место для адаптивного изображения. Нам требовалось нечто, определяющее только размерное соотношение изображения и позволяющее высоте уменьшаться вместе с шириной. И мы отыскали такое решение.

Хак Padding-Bottom

Эта техника основана на чем-то с названием intrinsic ratios (встроенные пропорции), но чего ни один член нашей команды не мог припомнить, понять или произнести термин “intrinsic”, и мы просто назвали его хаком “padding-bottom”.

Многие узнали об этом свойстве в 2009г. в статье A List Apart “Создание встроенных пропорций для видео” автора Терри Коблегца (Thierry Koblentz), и техника эта часто употребляется в адаптивных вебсайтах для вставки стороннего контента и медиа. С помощью этой техники мы определяем высоту как меру, относительную к ширине. У padding и margin имеются такие встроенные свойства, и мы можем пользоваться ими для создания соотношений размеров для элементов, не содержащих в себе контента.

Так как у padding есть эта способность, можно установить padding-bottom так, чтобы он был относителен ширине элемента. Если также установить высоту на 0, получится как раз то, что нам нужно.

.img-container {
	padding-bottom: 56.25%; /* соотношение 16:9 */
	height: 0;
	background-color: black;
}

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

.img-container {
	position: relative;
	padding-bottom: 56.25%; /* соотношение 16:9 */
	height: 0;
	overflow: hidden;
}

.img-container img {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
}

В контейнере резервируется необходимое место для изображения.

Теперь можно подстроить свой демо-пример, применив хак padding-bottom, и пользователь больше не заблудится в перерисовках, как это было раньше. Кроме того, кнопка «Назад» (“Back”) функционирует так, как ей положено. Смотрите новый видеоролик и демо.

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

Перед загрузкой изображения нам нужно знать его формат.

Изображения можно масштабировать больше их исходного размера.

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

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

Выбор способа загрузки изображения

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

Окончательный HTML должен быть одним тэгом img.

Элементы DOM должны быть минимальны.

Выполняться все должно как можно быстрее.

Не должно разрушаться при отключенном JavaScript’е.

На основании этой простой спецификации мы создали встроенный несложный JavaScript, базирующийся на технике noscript. Идея состоит в том, чтобы добавлять информацию о различных размерах изображения в HTML в качестве атрибутов данных тэга noscript. Содержимым тэга noscript станет тэг img, и будет показываться в браузерах с выключенным JavaScript’ом. Давайте посмотрим на разметку:

<noscript data-src-small="img-small.jpg" 
    data-src-medium="img-medium.jpg" 
    data-src-high="img-high" 
    data-src-x-high="img-x-high.jpg">
        <img src="img-small.jpg">
</noscript>

Тогда работа JavaScript’а состоит в анализе содержимого страницы, определении тех изображений, которые нужно подвергнуть «ленивой» загрузке, проверке размера экрана устройства и подборе подходящего изображения. Следующий код будет искать изображения для загрузки и вставки в DOM. Важно, чтобы JavaScript был встроен и загружался как можно быстрее после HTML. Скрипт также будет возвращать тэг alt из тэга noscript и вставлять его в свежесозданный тэг img.

var lazyloadImage = function (imageContainer) {

		var imageVersion = getImageVersion();

		if (!imageContainer || !imageContainer.children) {
			return;
		}
		var img = imageContainer.children[0];

		if (img) {
			var imgSRC = img.getAttribute("data-src-" + imageVersion);
			var altTxt = img.getAttribute("data-alt");
			if (imgSRC) {
				var imageElement = new Image();
				imageElement.src = imgSRC;
				imageElement.setAttribute("alt", altTxt ? altTxt : "");
				imageContainer.appendChild(imageElement);
				imageContainer.removeChild(imageContainer.children[0]);
			}
		}
	},
	lazyLoadedImages = document.getElementsByClassName("lazy-load");

	for (var i = 0; i < lazyLoadedImages.length; i++) {
		lazyloadImage(lazyLoadedImages);
	}

Подбор идеального изображения

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

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

Во-первых, подавляющее большинство держат свое устройство в книжной ориентации. Для чтения и просмотра статей книжная ориентация подходит отлично. И хотя размеры экранов сильно различаются, более 99% проанализированного нами трафика представляет устройства с шириной области просмотра либо 320, либо 360 px.

Во-вторых, у большинства посещающих сайт устройств высокоплотные экраны с исходной шириной в 480, 640, 720 или 1080 px. Самое высокое разрешение – у новых телефонов, таких как Galaxy S4 и Xperia Z; тогда как изображение шириной 1080 px на них смотрится отлично, тесты показали, что изображение шириной в 720 px тоже смотрелось бы достаточно хорошо, потребляя при этом меньше пропускной способности.

После анализа данных мы остановились на трех версиях каждого изображения:

Маленькое (small) (оптимизированное для экрана шириной 320 px),

Среднее (medium) (оптимизированное для экрана шириной 640 px),

Большое (large) (оптимизированное для экрана шириной 720 px).

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

Версиям мы даем логические имена вместо определения медиазапросов в разметке. Это сделано во имя гибкости. Так будет проще развивать JavaScript в будущем для, скажем, адаптации к скорости сети или создания возможности для пользователя установить отмену того, какое изображение использовать. В самом простом виде движок отбора версий изображения можно реализовать, как в следующем примере (хотя для поддержки Internet Explorer’а нам понадобится другая функция в качестве обходного маневра из-за отсутствия window.devicePixelRatio).

var getImageVersion = function() {
        	var devicePixelRatio = getDevicePixelRatio(); /* Функция где-то определена.*/
        	var width = window.innerWidth * devicePixelRatio;
        	if (width > 640) {
                    	return "high";
        	} else if (width > 320) {
                    	return "medium";
        	} else {
                    	return "small"; // версия по умолчанию
        	}
};

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

Приложения, внедряющие веб-обзоры, отчитались о сравнительном случайном разбросе высоты от 0 до 3000 px, а такие функции, как система TouchWiz от Samsung’а, у которой имеется режим разделения экрана, заставили нас отбросить высоту экрана как надежное значение при выборе размеров изображения.

Мы создали простую демо-страницу, где есть весь нужный JavaScript и CSS. Но помните, что наш код предназначен для мобильных устройств, поэтому не работает хорошо в, скажем, старых браузерах Internet Explorer.

Делаем изображения меньше

Большие красивые изображения тратят много пропускной способности. Скачать множество изображений шириной в 720 px в мобильной сети и займет много времени, и дорого обойдется пользователю. Хотя новый формат изображения, такой как WebP, может помочь некоторым пользователям, но он не поддерживается достаточным количеством браузеров, чтобы быть жизнеспособным в качестве единственного решения. К счастью, благодаря исследованию Даана Джобсиса (Daan Jobsis) мы можем воспользоваться тем фактом, что высокий уровень сжатия не слишком влияет на воспринимаемое качество изображения, если размеры изображения больше отображаемых, или если изображение показывается в его натуральную величину на высокоплотном экране.

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

Это также причина того, почему мы не включили версию изображения для экранов в 480 px. Уменьшение масштаба изображения шириной в 640 px с высоким уровнем сжатия вело к получению лучше смотрящегося изображения меньшего размера, чем мы могли добиться от изображения с исходным разрешением для экрана в 480 px. В таком случае, решили мы, стоит заставить устройство масштабировать изображение так, чтобы оно подходило.

КРАСНЫЕ ОБЛАСТИ ХОРОШО НЕ СЖИМАЮТСЯ

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

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

ПОИСК КОМПРОМИССА

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

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

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

Генерация разных изображений может оказаться проблемой. Мы пользуемся роскошью уже имеющегося серверного решения, которое способно масштабировать, сжимать и обрезать изображения по требованию. Запуск вашего собственного может повлечь много работы, но его реализация как, например, плагина WordPress (применяя класс WP_Image_Editor) действительно станет продвижением вперед.

Заключение

Три года прошло с момента представления Итаном Маркоттом (Ethan Marcotte) адаптивного вебдизайна, а мы все еще пытаемся отыскать хорошее решение проблемы управления изображениями. Все адаптивные решения являются в большей или меньшей степени хаком, и вышеописанное – не исключение. Но нам удалось избежать проблемы чрезмерной повторной заливки, мы не произвели множества ненужных элементов DOM, наш вебсайт поддается кэшированию, и мы предотвращаем загрузку неиспользуемых изображений.

На домашней странице Aftonbladet для мобильных устройств имеется около 40 изображений и, с помощью этой техники, она в итоге весит примерно 650 KB на «большом экране», 570 KB на среднем и 450 KB на маленьком (хотя размер меняется в соответствии с содержимым). Без сильного сжатия большие и средние версии будут по размеру более мегабайта. А в сравнении со старым вебсайтом нам удалось перейти от размытых изображений в низком разрешении к высококачественным, подогнанных под каждое устройство, получив при этом всего 25% увеличение размера закачки.

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

Автор: Anders Andersen & Tobias Järlund

Источник: http://mobile.smashingmagazine.com/

Редакция: Команда webformyself.

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки: ,

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree