Дисплеи с высокой плотностью пикселей быстро становятся нормой. Создателям контента необходимо адаптироваться к этому факту. Это краткое руководство о том, как сегодня предоставлять высококачественные изображения в Интернете без полифилов, JavaScript, хаков CSS и функций браузера, которые еще не реализованы. Одним словом: без кардинальных изменений в вашем рабочем процессе.
Сегодня существует множество предложений по адаптивным изображениям, многие из которых предполагают значительные изменения для веб-разработчика. Атрибут srcset
<img>
стандартного трека сложно реализовать, особенно из-за сложности дополнительного выбора srcset
на основе области просмотра:
banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x
Несмотря на то, что свойство CSS image-set
использует только devicePixelRatio
чтобы решить, какое изображение загружать, оно все равно заставляет разработчиков писать много дополнительной разметки для каждого изображения.
Другие предложения, такие как элемент <picture>
, еще более многословны. Более того, они не соответствуют стандартам, поэтому их повсеместная доступность даже дальше, чем атрибут srcset. Единственная альтернатива — JavaScript и серверные решения, но у этих подходов есть свои недостатки, о которых говорится в других статьях .
В этой статье мы рассмотрим несколько вариантов использования изображений, часто встречающихся в Интернете, и предложим простые решения, которые работают как на экранах с высокой плотностью пикселей, так и на обычных. Для целей этого обсуждения любое устройство, которое сообщает window.devicePixelRatio
больше 1, может считаться высоким DPI, поскольку это означает, что пиксели CSS не совпадают с пикселями устройства и что изображения масштабируются.
Вот краткое изложение:
- Если возможно, используйте CSS/SVG, а не растровые изображения.
- По умолчанию используйте изображения, оптимизированные для дисплеев с высокой плотностью изображения.
- Используйте PNG для простых рисунков и пиксельной графики (например, логотипов).
- Используйте сжатые файлы JPEG для изображений с различными цветами (например, фотографий).
- Всегда устанавливайте явные размеры (с помощью CSS или HTML) для всех элементов изображения.
Простые рисунки и пиксель-арт
Маленьких изображений часто можно полностью избежать, используя функции CSS или SVG. Например, нет необходимости использовать изображения для закругленных углов, поскольку свойство CSS border-radius
широко поддерживается. Аналогично, широко поддерживаются пользовательские шрифты, поэтому использование «изображенного» текста нецелесообразно.
Однако в некоторых случаях, например, в случае логотипов, изображение может быть единственным способом продвижения вперед. Например, этот логотип Chrome имеет естественный размер 256x256. На дисплее Retina вы можете увидеть сглаживание линий по диагоналям и кривым, что выглядит коренастым и некрасивым, особенно по сравнению с четко визуализированным текстом:
Естественные размеры: 256x256px
, размер ресурса: 31 kB
, формат: PNG
Убежденный? Хороший. Теперь давайте воспользуемся изображением высокой плотности. У вас может возникнуть соблазн сэкономить место, сохранив логотип в формате JPEG, но это может быть не очень хорошей идеей, поскольку сохранение логотипов и другой графики в формате с потерями приводит к появлению артефактов. В данном случае я преувеличил проблему, применив очень сильное сжатие, но обратите внимание на полосы на градиентах, крапинки на белом фоне и беспорядочные линии:
Естественные размеры: 512x512px
, размер ресурса: 13 kB
, формат: JPEG
Для относительно небольших изображений следует использовать 2x PNG. Имейте в виду, что разница в размере между PNG 1x и 2x обычно довольно велика (в данном случае 52 КБ). Однако в случае с логотипом это лицо вашего сайта и первое, что увидят ваши посетители. Если слишком экономить на качестве в обмен на размер, это будет последнее, что увидят ваши посетители!
Вот логотип Chrome во всей красе, уменьшенный вдвое от естественных размеров для 2x дисплеев:
Естественные размеры: 512x512px
, размер ресурса: 83 kB
, формат: PNG
Разметка для выполнения приведенного выше рендеринга следующая:
<img src="chrome2x.png" style="width: 256px; height: 256px;"/>
Обратите внимание, что я указал ширину и высоту изображения. Это необходимо, поскольку естественный размер изображения составляет 512 пикселей. Это также хорошо сказывается на производительности, поскольку механизм рендеринга хорошо понимает размер элемента и ему не нужно слишком усердно работать, чтобы его вычислить.
Одна из возможных оптимизаций, которая может сработать, — уменьшить 24-битный PNG до 8-битного с палитрой. Это работает для изображений с небольшим количеством цветов, включая логотип Chrome. Чтобы выполнить эту оптимизацию, вы можете использовать такой инструмент, как http://pngquant.org/ . Здесь вы можете увидеть небольшие полосы, но размер этого файла составляет всего 13 КБ, что означает колоссальную экономию в 6 раз по сравнению с исходным PNG размером 512x512.
Естественные размеры: 512x512px
, размер ресурса: 13 kB
, формат: PNG, 8-bit palette
Изображения с различными цветами
Я написал статью на HTML5Rocks , в которой рассмотрел ряд различных методов адаптивного изображения , а также провел небольшое исследование сжатия 1x и 2x JPEG и сравнения полученных размеров и визуального качества. Вот одна из таких плиток из статьи выше:
Я пометил изображения, указав уровень сжатия (обозначенный качеством JPEG), их размер (в байтах) и мое субъективное мнение об их сравнительной визуальной точности (ранжирование по цифрам). Интересно здесь то, что сильно сжатое изображение 2x (помечено 3) меньше по размеру и выглядит лучше , чем несжатое изображение 1x (помечено 4). Другими словами, между изображениями 4 и 3 нам удалось улучшить качество изображения, удвоив каждое измерение и значительно увеличив сжатие, одновременно уменьшив размер на 2 КБ.
Сжатие, размеры и визуальное качество
Я хотел получить немного больше информации о компромиссах между уровнем сжатия, размерами изображения, визуальным качеством и размером изображения. Я провел исследование со следующей гипотезой, основанной на исследовании выше:
Гипотеза
При достаточном сжатии изображение с увеличением 2x будет выглядеть эквивалентно тому же изображению с размером 1x при другом (более низком) сжатии. Однако в этом случае сильно сжатое изображение 2x будет меньше по размеру, чем изображение 1x.
Процесс
- Учитывая изображение 2x, сгенерируйте изображение 1x.
- Сжимайте оба изображения на разных уровнях.
- Создайте тестовую страницу, на которой оба набора изображений будут показаны рядом.
- Найдите в двух наборах место, где изображения эквивалентны.
- Обратите внимание на эквивалентные размеры изображений и уровни сжатия.
- Попробуйте это как на дисплее 1x, так и на дисплее 2x.
Я создал приложение для параллельного сравнения изображений, похожее на представление сравнения в Lightroom . Цель состоит в том, чтобы показать изображения с увеличением 1x и 2x рядом друг с другом, а также позволить вам увеличивать любую часть изображения, чтобы получить более подробную информацию. Вы также можете выбрать форматы JPEG и WebP и изменить качество сжатия, чтобы сравнить размер файла и качество изображения. Идея состоит в том, чтобы настроить параметры нескольких изображений, выяснить, какое качество сжатия, масштабирование и формат по сравнению с качеством изображения вам удобно, и использовать эти настройки для всех ваших изображений.
Сам инструмент доступен для игры . Вы можете увеличить изображение , выбрав подобласть для увеличения.
Анализ
Сразу скажу, что качество изображения — вещь субъективная. Кроме того, ваш конкретный вариант использования, скорее всего, будет определять, где находятся ваши приоритеты в отношении визуальной точности и размера размера файла. Кроме того, разные функции изображения по-разному реагируют на масштабирование и качество сжатия, поэтому универсальное решение здесь не обязательно подойдет. Цель этого инструмента — помочь вам получить представление о сжатии, масштабах и форматах качества изображения.
Поигравшись с зуммером изображения, мне быстро стали очевидны некоторые вещи. Во-первых, я предпочитаю изображения quality=30 dpr=2x
изображениям quality=90 dpr=1x
для увеличения детализации. Эти изображения также сопоставимы по размеру файла (в плоском случае сжатое изображение 2x имеет размер 76 КБ, тогда как несжатое изображение 1x — 80 КБ).
Исключением из этого правила являются сильно сжатые ( quality<30
) изображения с градиентами. Они, как правило, страдают от цветных полос, что одинаково плохо независимо от масштаба изображения. Образцы птиц и автомобилей, найденные в инструменте, являются тому примером.
Изображения WebP выглядят намного чище, чем JPEG, особенно при низких уровнях сжатия. Эта цветовая полоса кажется гораздо меньшей проблемой. Наконец, изображения WebP намного компактнее.
Предостережения и плавник
Обеспечение хорошего качества изображений на дисплеях с высокой плотностью изображения — это лишь половина проблем, связанных с изображением, вызванных огромными различиями в экранах. В некоторых случаях вам может потребоваться отображать совершенно разные изображения в зависимости от размера области просмотра. Например, снимок головы Обамы может подойти для экрана размером с телефон, но подставка перед ним и флаг позади него, а некоторые могут лучше подойти для дисплея ноутбука.
Я сознательно избегал этой темы «художественного направления», чтобы сосредоточиться только на изображениях с высоким разрешением. Эту проблему можно решить несколькими различными способами: с помощью медиа-запросов и фоновых изображений, с помощью JavaScript, с помощью некоторых новых функций, таких как image-set
, или на сервере. Эта тема рассматривается в разделе «Изображения с высоким разрешением и переменной плотностью пикселей» .
Подпишусь с несколькими открытыми вопросами:
- Влияние высокого сжатия на производительность. Каковы последствия декодирования сильно сжатых изображений?
- Каковы потери производительности при уменьшении размера изображения при загрузке изображения с увеличением 2x на дисплей с разрешением 1x?
Подводя итог, выберите CSS и SVG вместо использования растровых изображений. Если растровые изображения строго необходимы, используйте PNG для изображений с ограниченной палитрой и множеством сплошных цветов и используйте JPEG для изображений с множеством цветов и градиентов. Самое замечательное в этом подходе то, что ваша разметка практически не меняется. Все, что требуется от веб-разработчика, — это сгенерировать 2x-ресурсы и правильно изменить размер изображений в DOM.
Для дальнейшего чтения ознакомьтесь со статьей Скотта Джела на аналогичную тему. Пусть ваши изображения будут четкими, а использование сотовых данных будет низким!