Как использовать WebP и стоит ли?
Перевод статьи: https://css-tricks.com/using-webp-images/
Автор: Jeremy Wagner
Источник: CSS-Tricks
Опубликована: 26 августа 2016
Обновлена: 2 мая 2019
Всем иногда нравится позалипать на сайтах с огромным количеством красивых картинок — особенно, если это какая-нибудь вкусная еда, крутые гаджеты или что-то другое, не менее привлекательное для нас. Эти картинки вызывают в нас определённые чувства или, говоря со стороны маркетинга, вызывают в нас желание совершать определённые действия.
Но несмотря на всю пользу изображений в качестве маркетингового инструмента, часто картинки на сайтах бывают, откровенно говоря, просто огромны. Невероятно огромны. Иногда (например, на слабеньком мобильном интернете) можно даже наблюдать как они неторопливо прогружаются по частям сверху вниз… Вас уже накрыла светлая грусть по старым добрым временам dial-up соединений? (Меня нет)
На самом деле, такое поведение изображений — действительно проблема, поскольку они — значительная часть ресурсов, загружающихся при посещении почти любого сайта, и не зря. Картинки — очень выразительный инструмент, они могут рассказать гораздо больше, чем текст. И главный челлендж здесь — суметь поймать баланс между визуально богатым контентом сайта и его быстрой загрузкой.
Решение этой дилеммы неоднозначно — есть куча разных техник сжатия и отправки неоптимальных изображений в зависимости от возможностей девайса, который собирается их загрузить. Эта тема даже достойна отдельной книги, но в этой статье мы сфокусируемся лишь на одной теме: формат изображений WebP
от Google и преимущества, которые вы получите от использования изображений, выглядящих ровно так же, как и до сжатия, но имеющих значительно меньший вес. Что ж, приступим!
Что ещё за WebP и зачем он нужен?
WebP
был разработан и впервые продемонстрирован Google в 2010 году. Он поддерживает кодировку изображений и в lossy
, и в lossless
, что и делает его универсальным форматом для любых типов визуального медиа-контента и прекрасным соперником широко известным JPEG
и PNG
. Качество WebP
-изображений вполне сопоставимо с изображениями более распространённых форматов. Ниже — разница между lossy WebP
и JPEG
:
На примере выше фото визуально почти одинаковы, зато разница их размеров вполне существенна. Вес JPEG
-версии (слева) — 56.7 KB, версии в WebP
-формате (справа) примерно на треть меньше — 38KB. Неплохо, учитывая, что на первый взгляд качество этих изображений почти неразличимо.
Следующий вопрос, конечно же, браузерная поддержка. Кстати, она не настолько слабая, как можно было бы думать. Поскольку WebP
— Google-технология, её поддержка автоматически существует во всех браузерах на основе движка Blink. Эти браузеры охватывают достаточно большую долю пользователей по всему миру — примерно 70% пользователей работают в браузерах, имеющих поддержку WebP
на момент написания этой статьи (на момент перевода статьи WebP
поддерживают ~80% браузеров — прим. пер.). Если у вас есть шанс ускорить загрузку сайта для минимум ⅔ ваших пользователей — разве вы упустите его? Думаю, нет.
Важно помнить, что WebP
, тем не менее, не является полной заменой JPEG
или PNG
. Вы можете использовать этот формат для браузеров, которые поддерживают его, однако также вам придётся хранить фоллбэк из старых добрых везде поддерживаемых форматов для всех остальных. Это естественная ситуация для web-разработки: иметь план А для готовых поддерживать его браузеров и держать наготове план B (и даже иногда план C) для менее способных.
Наконец с дисклеймерами покончено, давайте оптимизировать!
Конвертация изображений в WebP формат
Если вы “на ты” с Photoshop, проще всего включиться в работу с WebP
, используя WebP Photoshop Plugin. После его установки, при сохранении изображения через Save as (но не через Save for Web!) вы сможете выбрать между WebP
или WebP Lossless
форматом.
Какая между ними разница? Этот вопрос аналогичен сравнению JPEG
и PNG
: JPEG
изображения используют lossy
, PNG
— lossless
. Поэтому используйте обычный WebP
, когда конвертируете JPEG
, и WebP Lossless
для конвертации PNG
изображений.
Если вы сохраняете изображения в WebP
формате, используя плагин для Photoshop — он позаботится обо всём за вас. Выбираем WebP
для lossy
изображения и получаем панель вроде этой:
Это окно настроек даёт возможность во многом влиять на итоговый результат — можно выставить желаемое качество получаемого изображения — слайдер от 0 до 100 (как у JPEG
) и отрегулировать фильтры (шум, резкость, etc).
Я не очень доволен этим плагином по двум причинам. Первое —
в нём нет интерфейса Save for Web, поэтому сразу посмотреть, как будет выглядеть конечный вариант сохраняемого изображения со всеми применёнными настройками, не получится. И второе— если вы хотите конвертировать несколько изображений, вы будете вынуждены проделать все манипуляции с каждым из них по отдельности. Как программисту, мне гораздо проще использовать что-то вроде Node.js, чтобы иметь возможность сконвертировать все изображения разом.
Конвертация изображений в WebP формат с помощью Node
Node.js прекрасен, а для таких мастеров на все руки, как я, это не только способ написания серверного javascript, но и крайне продуктивный помощник в разработке веб-сайтов. В этой статье мы будем использовать Node для конвертации наших JPEG
и PNG
изображений в WebP
по несколько штук за раз с помощью Node-пакета imagemin
.
imagemin
— настоящий швейцарский нож для обработки изображений через Node, но пока мы остановимся лишь на конвертации исходных изображений в формат WebP
.
Не переживайте! Даже если вы никогда не пользовались Node раньше, эта статья поможет вам начать. Если вам не нравится сама идея использования Node как инструмента, просто используйте WebP
-плагин для Photoshop и пропустите эту часть.
Сперва нужно скачать Node.js и установить его — это займёт всего несколько минут. После установки откройте консоль, перейдите в папку вашего web-проекта и уже из неё, используя Node Package Manager (npm), установите сам imagemin
и imagemin-webp
плагин:
npm install imagemin imagemin-webp
Установка обычно не занимает больше минуты. После её завершения, откройте свой редактор кода и создайте файл с названием webp.js
в корневой папке проекта. Скопируйте туда следующий код:
Этот скрипт обработает все изображения формата JPEG
и PNG
из папки img
и конвертирует их в WebP
формат. Для PNG
мы установили опцию lossless
в значение true
, для JPEG
— коэффициент сжатия quality
в значение 65
. Не бойтесь экспериментировать с любыми из настроек imagemin-webp
— вся информация о них есть на странице плагина.
Скрипт выше предполагает, что все исходные изображения находятся в папке с названием img
. Если это не так, вы всегда можете поменять значения переменных PNGImages
и JPEGImages
, чтобы в них содержались нужные директории. На выходе все WebP
-изображения будут сохраняться так же в папку img
. Если вы хотите изменить путь до папки, в которую будет сохраняться результат — измените значение переменной outputFolder
на желаемое. Как только вы закончите с настройками и будете готовы начать, запустите в консоли следующую команду:
node webp.js
Данная команда запустит скрипт, который обработает все изображения и соберёт их WebP
копии в папку img
. Степень шока от результата сжатия пропорциональна тому, какие изображения и в каком количестве вы сжимаете. В моём случае исходная папка с JPEG имела суммарный вес 2.75 MB, а в процессе конвертации он сократился до 1.04 MB без хоть сколько-нибудь заметной потери в качестве изображений. Сжатие на 62% вообще безо всяких усилий!
Теперь, когда все изображения сконвертированы, наконец настало время их использовать. Начнём же!
Использование WebP в HTML
Использование WebP
в HTML
ничем не отличается от использования любых других изображений, верно? Просто влепить его в обычный <img>
и дело с концом:
<!-- Ну что может пойти не так? --><img src=”img/myAwesomeWebPImage.webp” alt=”WebP rules.” />
Действительно, это прекрасно работает… Но только в браузерах с поддержкой WebP
. Горе тем несчастным пользователям, кто хотел бы посмотреть ваш сайт в браузере без поддержки WebP
, если вы только WebP
и используете:
Это стрёмно, согласен, но так работает фронтенд, поэтому не отчаивайтесь. Некоторые фичи просто не работают в некоторых браузерах и не факт, что в ближайшее время начнут. И самый простой способ заставить WebP
работать как нам нужно — использовать тег <picture>
, чтобы определить фоллбэки на случай отсутствия поддержки WebP
:
<picture>
<source srcset=”img/awesomeWebPImage.webp” type=”image/webp”
<source srcset=”img/creakyOldJPEG.jpg” type=”image/jpeg”>
<img src=”img/creakyOldJPEG.jpg” alt=”Alt Text!”>
</picture>
В общем случае, это наверняка лучшее, что вы можете сделать, потому что это будет работать в любом браузере, даже если он не поддерживает сам тег <picture>
. Дело в том, что браузеры, не поддерживающие <picture>
, в любом случае отобразят картинку из тега <img>
. Но если вам важна именно полная поддержка <picture>
, можете взглянуть на этот скрипт.
Использование WebP изображений в CSS
Ситуация осложняется, когда перед нами встаёт необходимость использовать WebP
изображения в CSS
. В отличие от элемента <picture>
в HTML
, который красиво подменяется <img>
в нужных случаях, CSS
не имеет встроенной возможности подменять изображения на резервные, если те окажутся оптимальнее. Решения типа множественных фонов (multiple backgrounds) часто и вовсе загружают все исходные изображения, что на деле как-то совсем не смахивает на оптимизацию. Но решение есть и название ему — feature detection.
Modernizr
— известная библиотека распознавания фич, доступных в каждом конкретном браузере. WebP
как раз является одной из технологий, поддержку которых Modernizr
умеет распознавать. А самое крутое в этом — здесь вы можете создать свою сборку Modernizr
, которая будет определять только поддержку WebP
, ничего лишнего.
Вставьте кастомную сборку Modernizr
на свой сайт через тег <script>
, и при загрузке библиотека автоматически добавит один из двух классов элементу <html>
:
webp
— этот класс будет добавлен, если с поддержкойWebP
у браузера всё хорошо;no-webp
— класс будет добавлен, если браузер не поддерживаетWebP
.
С помощью этих классов вы сможете написать отдельные стили для каждого из случаев, используя фоновые изображения в соответствии с поддерживаемыми браузером форматами:
.no-webp .elementWithBackgroundImage {
background-image: url(“image.jpg”);
}.webp .elementWithBackgroundImage{
background-image: url(“image.webp”);
}
Вот и всё. Браузеры, поддерживающие WebP
, получат WebP
, остальные — фоллбэк со стилями, использующими поддерживаемые форматы изображений. Настоящий win-win. Но есть одно “но”…
А что если у пользователя отключен JavaScript?
Если вы используете Modernizr
, то вы обязаны подумать о тех пользователях, которые по тем или иным причинам отключили JavaScript
в браузере. Извините, но таков мир. Если вы собираетесь использовать feature detection, вы обязаны протестировать работу сайта с отключенным JavaScript
. При использовании feature detection, основанном на добавлении классов (как в способе выше), пользователи с отключенным JavaScript
вообще получат пустой экран вместо фоновой картинки — это произойдёт, потому что невыполнившийся скрипт просто не добавит никакого класса элементу <html>
, а значит стили для фоновых изображений не отработают.
Исправлять это начнём с того, что добавим класс no-js
тегу <html>
:
<html class=”no-js”>
Затем напишем небольшой инлайновый скрипт и поместим перед всеми остальными скриптами:
<script>
document.documentElement.classList.remove(“no-js”);
</script>
Этот скрипт при парсинге убирает класс no-js
у элемента <html>
.
Но чем он нам поможет? Когда JS
отключен, этот мини-скрипт не будет исполнен, соответственно, класс no-js
останется на элементе. А значит, мы сможем добавить ещё одно CSS
правило, ориентированное на пользователей с отключенным JS
и максимальную поддержку браузерами:
.no-js .elementWithBackgroundImage {
background-image: url(“image.jpg”);
}
Такой подход покрывает все базовые случаи: если JS
включен, инлайновый скрипт выполнится и уберёт класс no-js
ещё до того, как CSS
будет распарсен, поэтому JPEG
изображения не будут загружены, если браузер пользователя поддерживает WebP
. Если JavaScript
действительно выключен, класс не будет убран, а значит применятся стили для наиболее широко поддерживаемого варианта.
Соответственно, после того, что мы сделали выше, мы получим следующие юзкейсы:
- Пользователи, чей браузер поддерживает
WebP
, увидятWebP
. - Пользователи, чей браузер не поддерживает
WebP
, получатJPEG
илиPNG
. - Пользователи с отключенным
JavaScript
получатJPEG
илиPNG
.
Пожмите себе руку — только что вы научились использовать прогрессивный формат изображений под названием WebP
.
В завершение
WebP
— достаточно разносторонний формат изображений, который мы можем использовать вместо PNG
или JPEG
(если он поддерживается в каждом конкретном случае). Его использование приводит к существенному снижению суммарного веса изображений на вашем сайте, а, как мы уже знаем — всё, что снижает количество передаваемых данных, ускоряет загрузку страницы.
Есть ли у WebP
минусы? Несколько. Самый большой из них — вы вынуждены иметь два набора изображений для достижения наиполнейшей поддержки браузеров, которая может быть вообще невозможна для вашего веб-сайта по тем или иным причинам. Ещё один минус — нужно использовать JavaScript
, чтобы поддерживать WebP
в CSS
. И последнее, что стоит заметить — пользователи, которые будут сохранять себе WebP
-изображения с вашего сайта, могут просто не иметь возможности просмотреть их у себя на компьютере.
В итоге, сравнительно небольшие усилия несомненно стоят полученного результата — экономия на весе картинок улучшит пользовательский интерфейс вашего сайта, позволив ему быстрее загружаться. Думаю, пользователи, открывающие ваш сайт через мобильный интернет, особенно порадуются.
Ну что ж, а теперь — только вперёд, к использованию WebP
!