Pull to refresh

Оптимизируем графику с помощью WebP

Website development *HTML *
Sandbox

Блог разработчика интерфейсовКакая сейчас неделя? Какая сейчас учебная неделя? Четная или нечетная?

По данным сайта 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.

<img src="image.webp" onerror="this.onerror=null; this.src='image.png'">

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

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


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

Пример использования:
  • Добавить в шапку
    <script async src="simple-webp.min.js">
  • Вместо стандартных изображений, написать по шаблону
    <noscript data-webp><img src="example.png" alt=""></noscript>


Библиотека проверяет поддержку формата 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. Скачать архив с изображениями, на которых я производил сравнение можно по ссылке.


UPD #1 В комментариях VEG указал на некорректно проведенный тест, и предоставил ссылки тесты от Mozilla 2013 и 2014 года. В них видно что уровень сжатия у WebP и других форматов примерно на одном уровне. Профит от WebP в том, что при сильном сжатии изображения выглядят лучше.

UPD #2 Способ через NOSCRIPT имеет большой недостаток в SEO, т.к. картинки не проиндексируются. pepelsbey в комментариях предложил использовать .
Tags:
Hubs:
Total votes 17: ↑12 and ↓5 +7
Views 30K
Comments Comments 28