[Из песочницы] Оптимизируем графику с помощью WebP

2610e05020e843bd8663a6bf104bf933.png

По данным сайта Web Perfomance Today, средний вес страницы в 2015 году 1109 КБ. По прогнозам, к 2018 будет около 2 МБ. Загрузка изображений занимает в среднем 64% (711 КБ) всего времени загрузки страницы. Поэтому начинать оптимизацию скорости загрузки страницы нужно именно с графики.
Графика оптимизируется в двух направлениях:

  • уменьшение количества запросов
  • уменьшение веса графики


Для уменьшения запросов используются спрайты и вставка графики в через base64. Для уменьшения веса графика сжимается (с и без потерей качества).
К сожалению, сжатие часто приводит к плохому качеству и небольшому выигрышу в размере. Возможно поэтому Google в 2010 году создал свой формат сжатия изображений — WebP.

Поддержка


Поверим Can I Use, который говорит что WebP поддерживается на 64,77% в мире и 56,22% в России, что дает нам основание использовать его. Из браузеров это Chrome, Opera, Opera Mini, Android Browser, Chrome for Android.

Тестируем сжатие


Перед использованием WebP, проверим насколько это эффективно. Я скачал по 12 изображений png и jpg. И сравнил размеры до и после оптимизации:

  • Оригинальные файлы — 6,7 МБ
  • После сжатия — 5,4 МБ
  • Оригинальные в формате WebP — 1,6 МБ
  • После сжатия в формате WebP — 1,8 МБ

Выигрыш в размере получился 3.8 МБ, т.е 70.3%. Поскольку изображения в среднем это 64%, то выигрыш в скорости загрузки страницы составит ~44.8% для пользователей, чьи браузеры поддерживают WebP!

Используем WebP


Использовать новый формат можно через тег img и через css свойство background. Конечно не забудем про пользователей без поддержки этого формата.

Чтобы определить поддержку WebP, можно воспользоваться Modernizr или снипетом. После этого написать fallback:

.no-webp .logo { background-image: url(logo.png); }
.webp .logo { background-image: url(logo.webp); }


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

Еще один способ — запрашивать изображение в формате WebP, если оно не загрузится, то показывать PNG.




У этого способа похожая проблема — если браузер не поддерживает WebP, он будет делать по 2 запроса на каждую картинку, что увеличит время загрузки.

Другой вариант


Не найдя нативного решения, я написал небольшую библиотеку simple-webp, которая решает проблему двух запросов.

Пример использования:

Библиотека проверяет поддержку формата WebP, после этого добавляет/убирает класс webp/no-webp к html и если браузер поддерживает WebP, то библиотека заменит расширение вашего изображения на .webp и загрузит его. Иначе браузер загрузит изображение в оригинальном формате.

К примеру если браузер поддерживает WebP, то вместо example.png загрузится example.webp, если нет — example.png.

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

Библиотека находится в публичном доступе на Github, занимает 2 КБ в несжатом виде.

P.S. В примерах для оптимизации я использовал приложение под OS X — ImageOptim. Для конвертации в WebP — WebPonoize.

P.S. S. Скачать архив с изображениями, на которых я производил сравнение можно по ссылке.

© Habrahabr.ru