Как использовать WebP и стоит ли?

Инна Погорелова
9 min readAug 3, 2019

--

Перевод статьи: 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:

Найдёте отличия? (Подсказка: WebP справа)

На примере выше фото визуально почти одинаковы, зато разница их размеров вполне существенна. Вес 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, PNGlossless. Поэтому используйте обычный WebP, когда конвертируете JPEG, и WebP Lossless для конвертации PNGизображений.

Если вы сохраняете изображения в WebP формате, используя плагин для Photoshop — он позаботится обо всём за вас. Выбираем WebP для lossy изображения и получаем панель вроде этой:

Диалоговое окно с настройками 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>:

  1. webp — этот класс будет добавлен, если с поддержкой WebP у браузера всё хорошо;
  2. 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 действительно выключен, класс не будет убран, а значит применятся стили для наиболее широко поддерживаемого варианта.

Соответственно, после того, что мы сделали выше, мы получим следующие юзкейсы:

  1. Пользователи, чей браузер поддерживает WebP, увидят WebP.
  2. Пользователи, чей браузер не поддерживает WebP, получат JPEG или PNG.
  3. Пользователи с отключенным JavaScript получат JPEG или PNG.

Пожмите себе руку — только что вы научились использовать прогрессивный формат изображений под названием WebP.

В завершение

WebP — достаточно разносторонний формат изображений, который мы можем использовать вместо PNG или JPEG (если он поддерживается в каждом конкретном случае). Его использование приводит к существенному снижению суммарного веса изображений на вашем сайте, а, как мы уже знаем — всё, что снижает количество передаваемых данных, ускоряет загрузку страницы.

Есть ли у WebP минусы? Несколько. Самый большой из них — вы вынуждены иметь два набора изображений для достижения наиполнейшей поддержки браузеров, которая может быть вообще невозможна для вашего веб-сайта по тем или иным причинам. Ещё один минус — нужно использовать JavaScript, чтобы поддерживать WebP в CSS. И последнее, что стоит заметить — пользователи, которые будут сохранять себе WebP-изображения с вашего сайта, могут просто не иметь возможности просмотреть их у себя на компьютере.

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

Ну что ж, а теперь — только вперёд, к использованию WebP!

--

--