[Из песочницы] Оптимизируем графику с помощью WebP
По данным сайта 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. Скачать архив с изображениями, на которых я производил сравнение можно по ссылке.