Дисплеи с высокой плотностью пикселей быстро становятся нормой. Создателям контента необходимо адаптироваться к этому факту. Это краткое руководство о том, как сегодня предоставлять высококачественные изображения в Интернете без полифилов, 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.
Для дальнейшего чтения ознакомьтесь со статьей Скотта Джела на аналогичную тему. Пусть ваши изображения будут четкими, а использование сотовых данных будет низким!