Главная » Хабрахабр » [Перевод] Оптимизация графики для веба: самое важное

[Перевод] Оптимизация графики для веба: самое важное

Автор электронной книги — Эдди Османи, один из руководителей разработки Google Chrome

Cжатие изображений всегда должно быть автоматизировано

Оптимизацию графики обязательно надо автоматизировать. О ней легко забыть, рекомендации меняются, да и сам контент может легко проскользнуть мимо конвейера сборки. Для автоматизации при сборке используйте imagemin или libvips. Есть и много других.

Большинство CDN (например, Akamai) и сторонних решений вроде Cloudinary, imgix, Fastly Image Optimizer, Instart Logic SmartVision и ImageOptim API предлагают комплексные автоматизированные решения для оптимизации изображений.

Но если всё-таки не хотите отдавать работу на аутсорсинг по соображениям стоимости или из-за дополнительной latency, то выбирайте приведённые выше варианты с открытым исходным кодом. На чтение статей и настройку конфигурации вы потратите время, которое дороже оплаты их услуг (у Cloudinary есть бесплатный тариф). Проекты Imageflow или Thumbor предлагают альтернативу на собственном хостинге.

Все должны эффективно сжимать изображения

Как минимум, используйте ImageOptim. Он значительно уменьшает размер при сохранении визуального качества. Есть версии под Windows и Linux.

Файлы PNG пропускайте через pngquant, а SVG — через SVGO. Более тщательный подход: прогоняйте JPEG-файлы через MozJPEG (для веб-контента приемлемо качество q=80 или ниже) и рассмотрите поддержку Progressive JPEG. Вместо сумасшедших гигантских анимированных GIF отдавайте пользователям видео H. Явно укажите очистку от метаданных (--strip для pngquant), чтобы избежать раздутия файлов. Если не можете себе это позволить, то хотя бы используйте Giflossy. 264 (или WebM для Chrome, Firefox и Opera)! Когда есть возможность потратить пару циклов CPU, а вам нужно изображение лучшего качества и вы готовы смириться с длительным временем кодирования, то попробуйте Guetzli.

Это можно использовать при выборе формата для выдачи: например, формат WebP для браузеров на основе Blink, таких как Chrome, и вариант JPEG/PNG для других браузеров. Некоторые браузеры анонсируют поддержку графических форматов через заголовок Accept.

Есть инструменты для генерации и выдачи srcset. Сжатие всегда можно улучшить. В браузерах на основе Blink выбор ресурсов автоматизируется с помощью client-hints — и вы сэкономите трафик на пользователях, которые указали в браузере опцию «экономия данных» через подсказку Save-Data.

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

Графика остаётся главной причиной ожирения веб-страниц

Изображения составляют огромную долю интернет-трафика. Согласно HTTP Archive, 60% объёма веб-страниц — это графика в форматах JPEG, PNG и GIF. По состоянию на июль 2017 года изображения составляли 1,7 МБ на средней веб-странице объёмом 3,0 МБ.

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


Исследование Soasta/Google от 2016 года показало, что иллюстрации — это второй предиктор конверсии, а у эффективных страниц на 38% меньше картинок

Выбор зависит от того, какую потерю качества считать приемлемой. Оптимизация изображений включает ряд мер.


Оптимизация: выбрать правильный формат, аккуратно сжать и установить приоритеты загрузки разных изображений

Типичная оптимизация включает сжатие, грамотную выдачу изображений на основе размера с помощью тегов <picture>/<img srcset> и изменение размера.


Согласно HTTP Archive, на 95-м процентиле (в кумулятивной функции распределения) каждая картинка поддаётся уменьшению на 30 КБ!

У нас ещё очень много изображений, которые можно оптимизировать.


Бесплатная программа ImageOptim уменьшает размер графики с помощью современных методов сжатия и удаления ненужных метаданных EXIF

Я нашёл, что он экономит массу времени. Если вы дизайнер, есть ещё плагин ImageOptim для Sketch, который оптимизирует ресурсы при экспорте.

Проведите аудит сайта с помощью WebPageTest.org.


В разделе Compress Images отчёта WebPageTest перечислены картинки, которые можно сжать более эффективно, при этом оценивается потенциальный выигрыш по размеру файлов

Он показывает картинки, которые можно сжать сильнее и которые можно поставить в ленивую загрузку. Сервис Lighthouse тоже осуществляет аудит производительности, в том числе проводит проверку оптимизации изображений.

Начиная с Chrome 60 этот сервис работает в панели аудита Chrome DevTools:


Lighthouse проводит аудит с прицелом на производительность, лучшие практики или прогрессивные функции веб-приложений (на выбор)

Вам могут быть известны другие инструменты аудита, такие как PageSpeed Insights и Website Speed Test от Cloudinary, включающий подробный аудит изображений.

Как отметил Илья Григорик в своём превосходном руководстве по оптимизации изображений, «правильный формат» сочетает в себе желаемый визуальный результат и функциональные требования. У вас растровая или векторная графика?

Они не зависят от разрешения или масштаба. Растровая графика кодирует значения каждого пикселя на прямоугольной сетке пикселей. Растровая графика используется там, где нужен фотореализм. С такой графикой хорошо справляются WebP или широко поддерживаемые форматы, такие как JPEG или PNG. Guetzli, MozJPEG и другие упомянутые инструменты подходят для растровой графики.

Она предлагает высокое разрешение и масштабирование. Векторная графика применяет точки, прямые и полигоны для представления изображений с простыми геометрическими фигурами (например, логотипов). Для такого варианта лучше подходят форматы вроде SVG.

Менять формат следует с осторожностью, проведя эксперименты с возможной экономией в разных форматах. Выбор неправильного формата дорого вам обойдётся.

Джереми Вагнер в своей лекции осветил компромиссы, которые стоит учитывать при оценке разных форматов в процессе оптимизации.

Вероятно, JPEG — самый популярный в мире формат графики. Как отмечалось ранее, 45% изображений на сайтах в HTTP Archive — это картинки JPEG. Ваш телефон, цифровая камера, старая веб-камера — все они обычно поддерживают данный кодек. Он очень древний, используется аж с 1992 года. За это время проведено огромное количество исследований, как улучшить компрессию JPEG.

Задача состоит в максимальном сохранении визуальной точности с минимизацией размеров файлов. JPEG — алгоритм сжатия с потерями, который отбрасывает «лишнюю» информацию для экономии места.

Какое качество изображений приемлемо в вашем случае?

Форматы вроде JPEG лучше всего подходят для фотографий или изображений с большим количеством цветов. Большинство инструментов оптимизации позволит выбрать приемлемый уровень сжатия: более сильное сжатие уменьшает размер файлов, но может привнести артефакты: гало или блочность.

Заметьте, что показатели качества изображения в разных инструментах могут сильно отличаться
Видимые артефакты сжатия JPEG нарастают по мере перехода от наилучшего качества к худшему.

При выборе уровня сжатия следует учитывать, какое качество необходимо для изображений:

  • Самое лучшее: когда качество важнее, чем размер файла. Это может быть связано с тем, что изображение занимает видное место в дизайне или отображается в полном разрешении.
  • Хорошее: когда вы думаете об экономии трафика, но не хотите слишком заметно повлиять на качество картинки. Пользователям всё-таки важно и качество иллюстраций.
  • Низкое: когда вы заботитесь о минимальном трафике и миритесь с деградацией изображения. Такой профиль подходит для сетей с плохим покрытием и тонких каналов.
  • Самое низкое: экономия полосы имеет первостепенное значение. Пользователи согласны на довольно плохое качество ради более быстрой загрузки страниц.

Далее поговорим о режимах сжатия JPEG, которые сильно влияют на результат.

Качество можно рассматривать как отклонение от идеального исходника. Примечание: возможно, мы иногда переоцениваем качество изображения, которое нужно пользователям. Это субъективный показатель.

В формате JPEG есть ряд различных режимов сжатия. Три популярных: базовый (последовательный), прогрессивный JPEG (PJPEG) и сжатие без потерь.

Чем отличаются базовый (или последовательный) и прогрессивный JPEG?

Базовый JPEG (режим по умолчанию в большинстве редакторов и оптимизаторов) кодирует и декодирует относительно просто: сверху вниз. Когда базовый JPEG загружается по медленному или нестабильному соединению, пользователь сначала увидит верхнюю часть картинки. Режим сжатия JPEG без потерь похож на базовый, только с меньшей степенью сжатия.


Базовый JPEG (baseline JPEG) загружается сверху вниз, а прогрессивный JPEG загружается от размытого до резкого

Первый проход показывает картинку в размытом виде и низком качестве, а последующие проходы постепенно улучшают качество. Прогрессивный JPEG делит изображение на ряд проходов. В конце концов создаётся полноценное изображение. Каждый проход повышает уровень детализации.

PJPEG сначала показывает размытую картинку, а потом повышает разрешение.
Базовый JPEG загружает изображение сверху вниз. Пэт Минан разработал интерактивный инструмент для тестирования и изучения прогрессивных файлов JPEG

Такие инструменты, как jpegtran, обеспечивают сжатие без потерь, перестраивая сжатые данные без ухудшения качества изображения. Оптимизация JPEG без потерь достигается путём удаления EXIF-заголовков от цифровых камер и редакторов, оптимизации таблиц Хаффмана и повторного сканирования изображения. jpegrescan, jpegoptim и mozjpeg (которые мы скоро рассмотрим) тоже поддерживают сжатие JPEG без потерь.

Преимущества прогрессивных JPEG

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

Это может оказаться удобнее, чем загрузка изображения сверху вниз, как в базовом JPEG. На медленных 3G-соединениях это позволяет примерно увидеть картинку, когда получена только часть файла — и принять решение, дожидаться его полной загрузки или нет.

Они смогли показать изображение хорошего качества на 15% быстрее, чем раньше, оптимизировав воспринимаемое время загрузки, как показано на рисунке выше
В 2015 году Facebook перешёл на PJPEG (для своего приложения iOS) и трафик уменьшился на 10%.

Более высокий коэффициент сжатия достигается благодаря тому, что на каждом проходе может составляться отдельная таблица Хаффмана. PJPEG может уменьшить размер файла на 2−10% по сравнению с базовым/простым JPEG для изображений более 10 КБ. Современные JPEG-кодеры (например, libjpeg-turbo, MozJPEG и др.) используют гибкость PJPEG для лучшего сжатия данных.

Потому что блоки базового JPEG кодируются по одному, а в PJPEG коэффициенты дискретного косинусного преобразования из нескольких блоков можно кодировать вместе, что приводит к лучшему сжатию. Примечание: почему PJPEG сжимает лучше?

Кто использует прогрессивный JPEG в продакшне?

  • Twitter.com выдаёт прогрессивные JPEG с базовым уровнем качества 85%. Они замерили субъективную задержку, воспринимаемую пользователем (время до первого прохода и общее время загрузки), и решили, что PJPEG в целом подходит исходя из качества компрессии, скорости кодирования и декодирования.
  • Facebook выдаёт прогрессивные JPEG в приложении iOS. Это на 10% уменьшило трафик и на 15% ускорило выдачу изображений «хорошего качества».
  • Yelp перешёл на прогрессивный JPEG. Это одна из мер, которая уменьшила размер изображений примерно на 4,5%. Она сократился ещё на 13,8% за счёт MozJPEG.

Многие другие сайты с большим количеством графических файлов, такие как Pinterest, тоже используют прогрессивный JPEG в продакшне.

Для пользователей удобнее, когда картинка проявляется постепенно
На сайте Pinterest изображения кодируются только в прогрессивном JPEG.

Недостатки прогрессивного JPEG

Декодирование PJPEG медленнее, чем базового JPEG — иногда втрое медленнее. На десктопных машинах с мощными процессорами это не так важно, как на мобильных устройствах с ограниченными ресурсами. Отображение неполных слоёв требует работы, поскольку вы фактически декодируете изображение несколько раз. Эти множественные проходы съедают циклы CPU.

Прогрессивное кодирование очень маленьких изображений (например, миниатюр для предпросмотра) может увеличить их размер. Также картинки в прогрессивном JPEG не всегда меньше по размеру. И для таких картинок рендеринг в несколько проходов вообще имеет мало смысла.

Так что перед выбором PJPEG желательно поэкспериментировать и найти правильный баланс между размером файла, сетевой задержкой и использованием CPU.

Это не снижает потребление памяти, но уменьшает нагрузку на процессор. Примечание: на мобильных устройствах может поддерживаться аппаратное декодирование PJPEG (и всех JPEG). Не во всех смартфонах Android есть аппаратное ускорение, но в устройствах высокого класса и в устройствах iOS оно есть.

Некоторые пользователи могут считать прогрессивную загрузку недостатком, так как она мешает понять, когда завершилась загрузка изображения. Попробуйте оценить, как к этому относится ваша аудитория.

Как кодировать файлы в формате прогрессивного JPEG?

Инструменты и библиотеки вроде ImageMagick, libjpeg, jpegtran, jpeg-recompress и imagemin поддерживают прогрессивный JPEG. Если у вас уже налажен конвейер по оптимизации, то велика вероятность, что изменение способа кодирования JPEG не станет проблемой:

const gulp = require('gulp');
const imagemin = require('gulp-imagemin'); gulp.task('images', function () )) .pipe(gulp.dest('dist')); });

Большинство редакторов по умолчанию сохраняют в базовый JPEG.

В Photoshop нужно выбрать команду «Файл» → «Экспорт» → «Сохранить для веба», а там указать формат прогрессивного JPEG.
Большинство редакторов по умолчанию сохраняют в базовый JPEG, но это можно изменить в настройках. Sketch тоже поддерживает экспорт Progressive JPEG путём установки флажка в меню экспорта JPG

Цветовая субдискретизация

Наши глаза хуже замечают потерю цветности, чем яркости. Цветовая субдискретизация (chroma subsampling) — вид компрессии, снижающий точность цветопередачи за счёт яркости (luma). Это уменьшает размер файла до 15−17%, не влияя заметно на качество изображения. Субдискретизация также уменьшает использование памяти.

На чёрно-белых фотографиях нет цвета, но благодаря яркости они выглядят такими же детальными, как цветные аналоги. Контраст отвечает за резкость на картинке, поэтому luma очень важна. Цветность меньше влияет на зрительное восприятие.

Здесь иллюстрация из статьи «JPEG для крабов» Фредерика Кайзера
JPEG поддерживает различные типы подвыборки: отсутствие подвыборки, горизонтальная, горизонтальная+вертикальная.

Что они собой представляют? При обсуждении подвыборки обычно приводят ряд распространённых примеров: 4:4:4, 4:2:2 и 4:2:0. Здесь A — количество пикселей в строке, для JPEG это обычно 4, B — количество цветов в первой строке, а C — количество цветов во второй. Предположим, что подвыборка имеет формат A:B:C.

  • В 4:4:4 нет сжатия, цвет и яркость передаются полностью.
  • В 4:2:2 половинный сэмплинг по горизонтали и полный по вертикали.
  • В 4:2:0 используются цвета из половины пикселей первой строки.

Некоторые общие правила: субдискретизация (-sample 2x2) отлично подходит для фотографий. Примечание: jpegtran и cjpeg поддерживают отдельную конфигурацию яркости и цветности через флаг -sample (например, -sample 2x1). Наконец, 2x1 на тот случай, если нет уверенности, какой вариант использовать. Её лучше отключить (-sample 1x1) для скриншотов, баннеров и кнопок.

Уменьшив количество пикселей, можно значительно уменьшить размер цветовых компонентов, в конечном счете уменьшив размер файла.


Варианты цветовой субдискретизации для JPEG с качеством 80

Цветовая субдискретизация полезна для большинства изображений, хотя есть явные исключения: лучше не использовать её там, где цветовая детализация столь же важна, как яркость (например, медицинские снимки).

Чёткие края сложнее сжать с помощью JPEG, поскольку он разработан для лучшей обработки фотографических сцен с более мягкими переходами. Пострадают и картинки с изображением шрифтов.


В работе с текстом учебник «Изучение JPEG» рекомендует придерживаться субдискретизации 4:4:4 (1×1)

MozJPEG и libjpeg-turbo используют один метод, а более старые версии libjpeg — другой, который добавляет артефактов. Кстати: в спецификациях JPEG не указан точный метод цветовой субдискретизации, поэтому разные кодеры/декодеры поступают по-разному.

Если качество установлено в диапазоне 51−100, то субдискретизация не используется (4:4:4). Примечание: Photoshop автоматически выбирает цветовую субдискретизацию при «сохранении для веба». Это одна из причин, почему размер файла резко уменьшается при переключении качества с 51 на 50. Когда качество ниже, устанавливается 4:2:0.

Это модель цветового пространства RGB с гамма-коррекцией. Примечание: в обсуждении субдискретизации часто упоминается термин YCbCr. Если посмотреть ExifData, вы увидите YCbCr рядом с уровнями выборки. Y — это яркость с гамма-коррекцией, Cb — компонент chroma синего цвета, а Cr — красного.

Дополнительные сведения см. в статье «Почему вы не используете цветовую субдискретизацию?»

Улучшенный JPEG

Каково текущее состояние с форматами JPEG в интернете?

tl;dr: поддержка в браузерах сильно отличается. Если использовать современные разработки, то часто придётся выдавать разным браузерам разные форматы.

Качество сравнивается инструментами SSIM (структурное сходство) и Butteraugli, которые мы более подробно рассмотрим позже.
Различные современные форматы (и оптимизаторы) показывают качество сжатия при целевом размере файла 26 КБ.

  • JPEG 2000 (2000) — улучшение сжатия за счёт замены дискретного косинусного преобразования на вейвлеты. Поддержка в браузерах: десктопный Safari и iOS.
  • JPEG XR (2009) — альтернатива JPEG и JPEG 2000, поддерживающая HDR и широкие цветовые гаммы. Создаёт файлы меньшего размера, чем JPEG, со слегка с меньшей скоростью кодирования/декодирования. Поддержка в браузерах: Edge, IE.
  • WebP (2010) — основанный на прогнозировании блоков формат от Google поддерживает сжатие с потерями и без потерь. Обеспечивает лучшее сжатие, чем JPEG, и поддерживает прозрачность, как PNG. Не хватает настройки цветовой субдискретизации и прогрессивной загрузки. Скорость декодирования ниже, чем у JPEG. Поддержка в браузерах: Chrome, Opera. Экспериментальная поддержка в Safari и Firefox.
  • FLIF (2015) — формат сжатия без потерь, превосходящий PNG, WebP без потерь, BPG без потерь и JPEG 2000 без потерь по коэффициенту сжатия. Поддержка в браузерах: нет, но есть JS-декодер.
  • HEIF и BPG. С точки зрения сжатия они одинаковы, но поставляются в разных обёртках:
  • BPG (2015) — замена JPEG более эффективным сжатием на основе HEVC (High Efficiency Video Coding). Кажется, обеспечивает меньший размер файлов по сравнению с MozJPEG и WebP. Вряд ли получит широкую поддержку из-за проблем с лицензированием. Поддержка в браузерах: нет, но есть JS-декодер.
  • HEIF (2015) — формат для изображений и последовательностей изображений, закодированных HEVC с межкадровым предсказанием. Apple анонсировала на WWDC, что будет изучать переход c JPEG на HEIF в операционной системе iOS, что даст уменьшение размера файлов до двух раз. Поддержка в браузерах: нет на момент написания статьи. Должна появиться в десктопном Safari и iOS 11.

Если вам нравится воспринимать информацию в графическом виде, можете оценить один из этих инструментов визуального сравнения для некоторых из вышеперечисленных форматов.

Чтобы использовать любой из вышеперечисленных форматов, вероятно, придётся выдавать разные копии каждому из целевых браузеров. Таким образом, поддержка в браузерах сильно отличается. Мы в Google видим определённые перспективы WebP, поэтому вскоре разберём подробнее этот формат.

Это позволяет указать content-type на стороне сервера, вообще не меняя HTML-документ. Вы также можете выдавать разные форматы (например, WebP, JPEG 2000) с одним и тем же расширением .jpg (или любым другим) поскольку браузер может выбрать content-type для рендеринга независимо от расширения. Сервисы вроде Instart Logic используют такой подход.

Далее поговорим о ситуациях, когда нельзя выдавать изображения в разных форматах: здесь помогут JPEG-оптимизаторы.

JPEG-оптимизаторы

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

tl;dr: Какой JPEG-кодек с оптимизацией использовать?

  • Большинство файлов: MozJPEG
  • Если важно качество и вы согласны на длительное кодирование: Guetzli
  • Если нужна конфигурируемость:

Что такое MozJPEG?

Mozilla предлагает модернизированный JPEG-кодер — MozJPEG. По заявлению разработчиков, он уменьшает размер файлов JPEG до 10%. Файлы, сжатые MozJPEG, открываются во всех браузерах, а среди поддерживаемых функций — прогрессивное сканирование, треллис-квантование (удаление деталей, которые хуже всего сжимаются) и несколько продвинутых шаблонов таблиц квантования, которые помогают создавать более гладкие изображения High-DPI (хотя это возможно с ImageMagick, если вы готовы пробираться через дебри XML-конфигурации).

Вот пример реализации с помощью Gulp: MozJPEG поддерживается в ImageOptim и для него есть относительно надёжный настраиваемый плагин imagemin.

const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg'); gulp.task('mozjpeg', () => gulp.src('src/*.jpg') .pipe(imagemin([imageminMozjpeg({ quality: 85 })])) .pipe(gulp.dest('dist'))
);


MozJPEG: сравнение размера файлов и оценок визуального сходства на разном качестве

Для вычисления оценок SSIM (структурного сходства с исходным изображением) я использовал jpeg-compress из проекта jpeg-archive.

Для изображений малого и среднего размера MozJPEG (с качеством 80−85) уменьшает файлы на 30−40% с сохранением приемлемого SSIM и улучшением на 5−6% по jpeg-turbo. По моему опыту, MozJPEG — хороший вариант сжатия изображений для интернета с высоким качеством при одновременном уменьшении размера файла. Он кодирует медленнее базового JPEG, но разница не критична.

Автор книги «Веб-производительность в действии» Джереми Вагнер с успехом использовал программу в такой конфигурации. Примечание: если вам нужен инструмент, поддерживающий MozJPEG с дополнительной конфигурацией и некоторыми бесплатными утилитами для сравнения изображений, посмотрите на jpeg-recompress.

Что такое Guetzli?

Guetzli — многообещающий, но очень медленный, перцептивный JPEG-кодек от Google. Он пытается найти самый маленький JPEG, перцептивно неотличимый от оригинала. Кодек выполняет ряд экспериментов, предлагая варианты для сравнения, и учитывает психовизуальную ошибку каждого варианта. В качестве конечного результата выбирается вариант с наивысшей оценкой.

Guetzli учитывает некоторые свойства человеческого зрения, которые не принимаются в расчёт другими кодеками JPEG. Для измерения различия между изображениями Guetzli применяет Butteraugli — модель на основе человеческого восприятия (обсуждается ниже). Например, существует зависимость между количеством видимого зелёного света и чувствительностью к синему, поэтому изменения синего цвета около зелёного можно кодировать менее точно.

Между низким и высоким уровнями качества в формате JPEG намного, намного бóльшая разница, чем при смене кодека. Примечание: Размер файла намного сильнее зависит от выбора уровня кодирования, чем от выбора кодека. Обязательно обращайте внимание на этот показатель, чтобы он не оказался слишком высоким. Очень важно указать минимально приемлемый уровень качества.

Guetzli заявляет о разнице в размере файлов 20−30% без уменьшения оценки Butteraugli по сравнению с другими компрессорами. Большой недостаток Guetzli в его чрезвычайной медлительности, так что в настоящее время он подходит только для статического контента. В README указан большой объём потребляемой памяти: кодирование требует около 1 минуты и 200 МБ RAM на мегапиксель. На GitHub есть хороший тред с обсуждением реального опыта работы с Guetzli. Кодек идеально подходит для оптимизации изображений при сборке статического сайта, но в меньшей степени пригоден для запуска по требованию.

Инструменты вроде ImageOptim поддерживают оптимизацию Guetzli (в последних версиях).

const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminGuetzli = require('imagemin-guetzli'); gulp.task('guetzli', () => gulp.src('src/*.jpg') .pipe(imagemin([ imageminGuetzli({ quality: 85 }) ])) .pipe(gulp.dest('dist')) );

Это имеет смысл для архивного хранения фотографий с высоким разрешением. Кодирование Guetzli изображений 3000×3000 пикселей с разными уровнями заняло почти семь минут.


Guetzli: сравнение размеров файлов и оценки визуального сходства на разном качестве

Хотя эффект есть и на других изображениях (например, JPEG качества 84 или ниже), но результаты хуже. Примечание: рекомендуется запускать Guetzli на высококачественных изображениях (например, несжатых исходных изображениях, PNG или JPEG с качеством около 100%).

Guetzli тратит очень (очень) много времени и заставит по полной раскрутиться кулер CPU, но оно того стоит. Я видел ряд примеров, когда размер файлов уменьшался на 40% при сохранении визуальной точности. Это делает его идеальным выбором для архивирования фотографий. На изображениях малого и среднего размера тоже есть некоторая экономия (в диапазоне 10−15 КБ), но не настолько значительная. При сжатии совсем маленьких изображений Guetzli может привнести «жидкоподобные» искажения.

Для разнообразия вариантов использования вас может заинтересовать сравнение Guetzli с автоматическим сжатием Cloudinary в исследовании Эрика Портиса.

Сравнение MozJPEG и Guetzli

Сложно сравнивать разные кодеки JPEG: необходимо оценить и качество, и точность сжатого изображения, а не только размер. Как отмечает эксперт по сжатию изображений Корнель Лесински, бенчмарк только одного, а не обоих аспектов, может привести к неверным выводам.

Подход Корнеля: Как выглядят Guetzli и MozJPEG в сравнении?

  • Guetzli подходит для изображений более высокого качества (оптимальная оценка butteraugli считается для q=90+, а у MozJPEG — около q=75)
  • Guetzli намного медленнее (оба производят стандартные JPEG, поэтому декодирование одинаково быстрое, как обычно)
  • MozJPEG не выбирает автоматически настройку качества, но вы можете найти оптимальное качество с помощью внешнего инструмента, например, jpeg-archive

Существует ряд методов определения визуального или перцептивного сходства сжатых изображений с исходником. В исследованиях часто используется SSIM (структурное сходство). Однако Guetzli оптимизирован для Butteraugli.

Butteraugli

Система Butteraugli определяет момент, когда человек начинает замечать разницу (психовизуальное сходство) между двумя изображениями. Butteraugli не только даёт оценку, но и составляет пространственную карту уровня различий. В то время как SSIM суммирует все ошибки, Butteraugli ищет максимальные.

Это позволило уменьшить размер файла на 65%
В этом примере Butteraugli ищет минимальный порог качества JPEG, чтобы пользователь не заметил визуальной разницы между изображениями.

На практике вы определяете уровень визуального качества, а затем запускаете несколько стратегий оптимизации изображений, глядя на оценки Butteraugli, прежде чем выбрать результат, который соответствует оптимальному балансу размера файла и уровня сжатия.

Его использование относительно простое: укажите два изображения для сравнения (исходная и сжатая версия) — и получите оценку
Мне потребовалось около 30 минут для локальной настройки Butteraugli после установки Bazel и сборки исходников C++ для корректной компиляции на Mac.

Чем Butteraugli отличается от других способов оценки визуального сходства?

Один из разработчиков Guetzli говорит, что Guetzli лучше по оценке Butteraugli, хуже по SSIM, а MozJPEG примерно одинаково хорош по обеим метрикам. Это стратегию я использую для оптимизации изображений. Я запускаю Butteraugli и модуль Node вроде img-ssim для сравнения оценок SSIM до/после Guetzli и MozJPEG.

Объединение энкодеров?

Как показала практика, сочетание Guetzli и MozJPEG без потерь (jpegtran, а не cjpeg, чтобы не отбрасывать работу, проделанную Guetzli) позволяет дополнительно уменьшить размер файла на 10−15% (55% в целом) с весьма незначительным снижением оценки SSIM. Это требует проверки и анализа, но другие специалисты вроде Арии Хидаята попробовали — и получили такой же многообещающий результат.

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

WebP — последний графический формат от Google, который стремится уменьшить размеры файлов при сжатии без потерь и с потерями, обеспечивая приемлемое визуальное качество. Поддерживает альфа-канал (прозрачность) и анимацию.

WebP — не универсальный инструмент, но его популярность растёт. WebP совершенствуется: за прошлый год он прибавил несколько процентов в сжатии без потерь и с потерями, по скорости кодирования стал вдвое быстрее, а скорость декодирования увеличилась на 10%. Давайте рассмотрим, почему.


WebP: сравнение размеров файлов и оценки визуального сходства на разных уровнях качества

Как работает WebP?

Cжатие с потерями

Разработчики говорят, что при сжатии с потерями с использованием кодека VP8 или VP9 файлы уменьшаются в среднем на 25−34% по сравнению с JPEG.

Настройка среднего качества (-m 4 -q 75) — установленный по умолчанию баланс скорости и размера файла. В диапазоне низкого качества (0−50) у WebP большое преимущество перед JPEG, поскольку он размывает уродливые артефакты блочности. WebP рекомендуется там, где скорость важнее качества. В диапазоне высокого качества (80−99) преимущества WebP минимальны.

Сжатие без потерь

Файлы WebP со сжатием без потерь на 26% меньше файлов PNG. Время загрузки по сравнению с PNG уменьшается на 3%. Однако в интернете сжатие без потерь обычно не используется. Такой вариант лучше подойдёт для архивного хранения.

Прозрачность

У WebP есть 8-битный канал прозрачности со сжатием без потерь всего на 22% больше по байтам, чем у PNG. Он также поддерживает прозрачность RGB с потерями, это уникальная особенность WebP.

Метаданные

Формат WebP поддерживает метаданные фотографий EXIF и цифровых документов XMP, а также содержит цветовой профиль ICC.

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

Например, JPEG с качеством 70% будет сильно отличаться от изображения WebP с качеством 70%, потому что WebP достигает меньших размеров файлов, отбрасывая больше данных. Примечание: настройки качества WebP с потерями не соответствуют настройкам JPEG.

Кто использует WebP в продакшне?

Много больших компаний используют WebP в продакшне для снижения расходов и увеличения скорости загрузки страницы.

Google выдаёт 43 миллиарда изображений в день, 26% из которых сжаты без потерь. Google сообщил об экономии 30−35% на WebP по сравнению с другими схемами сжатия с потерями. Несомненно, она ещё увеличится, когда браузеры улучшат поддержку WebP. Это много запросов и значительная экономия. Google использует этот формат на Google Play, YouTube и других сайтах.

Издатель VoxMedia на 1−3 секунды уменьшил время загрузки страниц The Verge, перейдя на WebP для пользователей Chrome. Netflix, Amazon, Quora, Yahoo, Walmart, Ebay, The Guardian, Fortune и USA Today сжимают и выдают изображения WebP для браузеров, которые его поддерживают. Сайт 500px зафиксировал уменьшение размеров файлов в среднем на 25% с аналогичным или лучшим качеством.

Кроме вышеперечисленных, WebP используют и другие компании.


Использование WebP в Google: 43 миллиарда картинок WebP ежедневно выдаются на YouTube, Google Play, Chrome Data Saver и G+

Как работает кодирование WebP?

Для статических изображений WebP — альтернатива JPEG. В кодировании с потерями три ключевых этапа:

Это похоже на то, как JPEG преобразует цветовое пространство, разбивая его на блоки и понижая количество пикселей на каналах цветности. Macro-blocking — разделение изображения на (макро) блоки по 16×16 пикселей яркости и на блоки по 8×8 пикселей цветности.

Её определяют два набора пикселей вокруг блока: A (строка непосредственно сверху) и L (столбец слева). Прогнозирование — для каждого подблока 4×4 составляется модель прогнозирования, которая эффективно выполняет фильтрацию. Кольт Маканлис более подробно рассказывает об этом в статье о том, как работает WebP в режиме сжатия с потерями. С помощью этих двух наборов энкодер заполняет пикселями тестовый блок 4×4 и определяет, какие значения ближе всего к исходному блоку.

Ключевое отличие — использование арифметического сжатия, а не алгоритма Хаффмана, как в JPEG. Дискретное косинусное преобразование (DCT) применяется в несколько этапов, как в JPEG.

Для дополнительной информации рекомендую статью «Методы сжатия WebP» с сайта Google Developer.

Поддержка браузерами WebP

Не все браузеры поддерживают WebP, но по данным CanIUse.com, глобальная поддержка составляет около 74%. Chrome и Opera поддерживают формат. Safari, Edge и Firefox экспериментируют, но пока не реализовали поддержку в официальных версиях. Из-за этого выдача WebP зачастую зависит от веб-разработчика. Подробнее об этом позже.

Вот основные браузеры и информация о поддержке каждым из них:

  • Chrome: полная поддержка с версии 23
  • Chrome для Android: начиная с Chrome 50
  • Android: с 4.2
  • Opera: с 12.1
  • Opera Mini: все версии
  • Firefox: некоторая бета-поддержка
  • Edge: некоторая бета-поддержка
  • Internet Explorer: нет
  • Safari: некоторая бета-поддержка

WebP не лишён недостатков. В нём отсутствуют опции цветового пространства с полным разрешением и не поддерживается прогрессивное декодирование. Тем не менее, для WebP создан приличный инструментарий, а поддержки браузеров вполне хватает, чтобы рассматривать выдачу WebP как один из вариантов.

Как конвертировать изображения в WebP?

Несколько коммерческих и свободных редакторов поддерживают WebP. Одно из самых полезных приложений — XnConvert: это бесплатный кросс-платформенный пакетный конвертер.

Это распространённая ошибка, в результате которой генерируются изображения WebP с артефактами сжатия JPEG. Примечание: важно не допускать преобразования в WebP картинок JPEG низкого или среднего качества. Загружайте в конвертер файл максимального качества, желательно оригинал. Это снижает эффективность WebP, поскольку ему приходится сохранять и изображение, и искажения JPEG, что приводит к двойной потере качества.

XnConvert

XnConvert производит пакетную обработку изображений более чем 500 форматов. Вы можете объединить разными способами более 80 отдельных действий для преобразования или редактирования изображений.

Кроме сжатия, XnConvert умеет удалять метаданные, обрезать картинки, настраивать глубину цвета и выполнять другие преобразования
XnConvert поддерживает пакетную оптимизацию изображений, выполняя прямое преобразование из исходных файлов в WebP и другие форматы.

Некоторые параметры, перечисленные на веб-сайте xnview:

  • Метаданные: редактирование
  • Преобразования: поворот, обрезание, изменение размера
  • Регулировки: яркость, контраст, насыщенность
  • Фильтры: размытие, рельеф, резкость
  • Эффекты: маски, водяные знаки, виньетирование (частичное затемнение)

Результаты операций можно экспортировать примерно в 70 различных форматов файлов, включая WebP. XnConvert — бесплатная программа под Linux, Mac и Windows. Это отличный вариант, особенно для малого бизнеса.

Модули Node

Imagemin — популярный модуль сжатия изображений, у которого есть расширение для преобразования в WebP (imagemin-webp). Поддерживается сжатие с потерями и без потерь.

Для установки imagemin и imagemin-webp запустите:

> npm install --save imagemin imagemin-webp

Ниже мы используем кодирование с потерями с качеством энкодера WebP 60: Затем можем прописать require() в обоих модулях и запустить их на любых изображениях (например, JPEG) в каталоге проекта.

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp'); imagemin(['images/*.{jpg}'], 'images', { use: [ imageminWebp({quality: 60}) ] }).then(() => { console.log(‘Images optimized’);
});

Как и в JPEG, можно заметить артефакты сжатия на конечной картинке. Оцените сами, какой уровень сжатия адекватен для ваших файлов. Imagemin-webp также можно использовать для кодирования изображений WebP без потери качества (с поддержкой 24-битного цвета и полной прозрачности), указав параметр lossless: true:

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp'); imagemin(['images/*.{jpg,png}'], 'build/images', { use: [ imageminWebp({lossless: true}) ] }).then(() => { console.log(‘Images optimized’);
});

Плагин WebP для Gulp от Синдре Сорхуса сделан на базе imagemin-webp, есть ещё загрузчик WebP для WebPack. Плагин Gulp понимает все опции расширения imagemin:

const gulp = require('gulp');
const webp = require('gulp-webp'); gulp.task('webp', () => gulp.src('src/*.jpg') .pipe(webp({ quality: 80, preset: 'photo', method: 6 })) .pipe(gulp.dest('dist'))
);

Или сжатие без потерь:

const gulp = require('gulp');
const webp = require('gulp-webp'); gulp.task('webp-lossless', () => gulp.src('src/*.jpg') .pipe(webp({ lossless: true })) .pipe(gulp.dest('dist'))
);

Пакетная оптимизация изображений с помощью Bash

XNConvert поддерживает пакетное сжатие, но всё можно сделать из командной строки.

Пакетная конвертация изображений в формат WebP с помощью cwebp:

find ./ -type f -name '*.jpg' -exec cwebp -q 70 {} -o {}.webp \;

Оптимизация кодеком MozJPEG с использованием jpeg-recompress:

find ./ -type f -name '*.jpg' -exec jpeg-recompress {} {} \;

и обрезка SVG с помощью программы svgo (которую мы рассмотрим позже):

find ./ -type f -name '*.svg' -exec svgo {} \;

Джереми Вагнер написал более полную статью по оптимизации изображений в Bash и ещё одну — о распараллеливании этой задачи.

Другие приложения для обработки и редактирования WebP

  • Leptonica — целый веб-сайт свободных приложений для обработки и анализа изображений.
  • Sketch поддерживает сохранение в WebP.
  • GIMP — бесплатная альтернатива Photoshop с открытым исходным кодом.
  • ImageMagick — создание, компоновка, преобразование и редактирование растровой графики. Бесплатный, работает из командной строки.
  • Pixelmator — коммерческий редактор изображений для Mac.
  • Photoshop WebP Plugin — бесплатный плагин от Google. Импорт и экспорт изображений в Photoshop.

Для Android вы можете конвертировать существующие BMP, JPG, PNG и статические GIF-изображения в формат WebP с помощью Android Studio. Дополнительные сведения см. в разделе «Создание изображений WebP с помощью Android Studio».

Как просмотреть изображения WebP на моей ОС?

Хотя изображения WebP всегда открываются в браузере на движке Blink (Chrome, Opera, Brave), их можно просматривать непосредственно из ОС с помощью надстройки для Mac или Windows.

Здесь три ключевые проблемы: Несколько лет назад Facebook экспериментировал с WebP и заметил проблему: некоторые пользователи сохраняли картинки на диск, а потом не могли их открыть.

  • После сохранения не удаётся просмотреть файлы WebP локально. Это исправлено в Chrome, который теперь регистрирует на себя расширение .webp.
  • После сохранения изображение отправляется по электронной почте человеку, у которого нет Chrome. Facebook решил проблему, внедрив большую кнопку «Скачать», по которой отдаёт JPEG.
  • Копирование URL картинки с последующей публикацией в интернете решается путём согласования content-type.

У ваших пользователей такие проблемы могут не проявиться, но это интересная заметка на полях. К счастью, сегодня существуют утилиты для просмотра WebP под разные ОС.

Он неплохо работает: На Mac попробуйте плагин Quick Look для WebP (qlImageSize).

Под Windows можно загрузить пакет кодеков WebP, который добавляет опцию просмотра WebP в File Explorer и Windows Photo Viewer.

Как отдавать WebP?

Браузеры без поддержки WebP не покажут никакой картинки. Чтобы избежать этого, есть несколько стратегий.


Панель Chrome DevTools Network с выделением файлов типа WebP, которые отдаются в браузеры на движке Blink


Play Store отдаёт WebP браузерам на Blink и JPEG остальным, таких как Firefox

Вот некоторые варианты доставки изображений WebP пользователям:

Использовать .htaccess для выдачи копий WebP

Вот как использовать .htaccess для выдачи файлов WebP в поддерживаемых браузерах, если на сервере есть webp-версия файла JPEG/PNG.

Винсент Орбак рекомендовал такой подход:

В этом случае вы можете отдать с сервера WebP-версию изображения. Браузеры могут явно сигнализировать о поддержке WebP через заголовок Accept. Но это не всегда возможно (например, для статических хостов, вроде страниц GitHub или S3), поэтому обязательно проверьте, прежде чем рассматривать эту опцию.

Ниже приведён пример файла .htaccess для веб-сервера Apache:

<IfModule mod_rewrite.c> RewriteEngine On # Check if browser support WebP images RewriteCond %{HTTP_ACCEPT} image/webp # Check if WebP replacement image exists RewriteCond %{DOCUMENT_ROOT}/$1.webp -f # Serve WebP image instead RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] </IfModule> <IfModule mod_headers.c> Header append Vary Accept env=REDIRECT_accept </IfModule> AddType image/webp .webp

Если есть проблемы с отображением графики WebP, убедитесь, что на сервере включен MIME-тип image/webp.

На Apache добавьте в файл .htaccess следующий код:

AddType image/webp .webp

На Nginx добавьте в файл mime.types следующий код:

image/webp webp;

Примечание: Винсент Orback приводит образец htaccess для выдачи WebP, а Илья Григорик поддерживает коллекцию скриптов конфигурации для выдачи WebP, которые могут быть полезны.

Использование тега <picture>

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

Не размещайте источники image/webp после устаревших форматов, а ставьте перед ними. Примечание: будьте осторожны с порядком элементов <source>. Обычно получается такой же порядок, как при указании сначала более новых форматов. Вы также можете разместить изображения по возрастанию объёма файла, если у них одинаковый размер в пикселях (когда не используется атрибут media).

Вот некоторые примеры HTML:

<picture> <source srcset="/path/to/image.webp" type="image/webp"> <img src="/path/to/image.jpg" alt="">
</picture> <picture> <source srcset='paul_irish.jxr' type='image/vnd.ms-photo'> <source srcset='paul_irish.jp2' type='image/jp2'> <source srcset='paul_irish.webp' type='image/webp'> <img src='paul_irish.jpg' alt='paul'>
</picture> <picture> <source srcset="photo.jxr" type="image/vnd.ms-photo"> <source srcset="photo.jp2" type="image/jp2"> <source srcset="photo.webp" type="image/webp"> <img src="photo.jpg" alt="My beautiful face">
</picture>

Автоматическое преобразование в WebP на стороне CDN

Некоторые CDN поддерживают автоматическое преобразование и выдачу WebP по запросу клиента, когда это возможно. Проверьте свой CDN, есть ли у них поддержка. Возможно, проблема очень просто решается.

Поддержка WordPress

Jetpack: популярный плагин WordPress, включает в себя CDN-сервис изображений под названием Photon с поддержкой WebP. Он включён в бесплатную версию Jetpack, что очень практично и полезно. Недостаток в том, что Photon автоматически изменяет размеры изображения, помещает строку запроса в URL, а для каждого изображения выполняется дополнительный запрос к DNS.

В меню плагина Cache Enabler есть флажок для кэширования и выдачи изображений WebP, если браузер пользователя их поддерживает. Cache Enabler и Optimizer: если вы используете WordPress, есть как минимум один вариант с открытым исходным кодом. Здесь тоже недостаток: Cache Enabler требует использования родственной программы Optimizer, за которую взимают ежегодную плату. Это упрощает работу с WebP. Это не очень характерно для решений с открытым исходным кодом.

По функциональности Short Pixel очень похож на упомянутый Optimizer. Short Pixel: другой вариант оптимизатора для Cache Enabler, тоже платный. Позволяется бесплатно оптимизировать до 100 фотографий в месяц.

Сжатие GIF-анимаций и почему <video> лучше

Анимированные GIF по-прежнему широко используются, несмотря на их узкую специализацию. Хотя все, от социальных сетей до популярных медиа-сайтов, обильно использую GIF-анимацию, этот формат никогда не предназначался для видео или анимации. На самом деле спецификация GIF89a явно указывает, что «GIF не предназначен служить платформой для анимации». Количество цветов, количество кадров и пропорции — всё это влияет на размер анимированного GIF. Замена на видеоформат даёт максимальную экономию.


Сравнение размеров GIF-анимации и видео в эквивалентном качестве

Возможно, вы обратили внимание, что загруженные в Twitter анимации GIF работают там лучше, чем на других сайтах. Выдача того же видео в формате MP4 сокращает размер файла на 80% или больше. Кроме того, что файлы GIF впустую тратят трафик, они дольше загружаются, содержат меньше цветов и обычно выглядят не очень приятно. Чтобы улучшить качество и уменьшить трафик, Twitter автоматически преобразует их в видео. Это потому что анимированные GIF в Twitter на самом деле не являются GIF-файлами. Аналогично, Imgur при загрузке конвертирует GIF в MP4.

Потому что они хранят каждый кадр как GIF-изображение без потерь — да, без потерь. Почему GIF-файлы во много раз больше про размеру? Формат не анализирует соседние кадры для сжатия, в отличие от видеокодеков вроде H. Плохое качество GIF вызвано не сжатием, а палитрой в 256 цветов. Видео MP4 хранит каждый ключевой кадр как JPEG с потерями, отбрасывая часть исходных данных для достижения лучшего сжатия. 264.

Если можете переключиться на видео

Если приходится использовать анимированные GIF

  • Инструменты вроде Gifsicle удаляют метаданные, неиспользуемые цвета палитры и минимизируют изменения между кадрами.
  • Рассмотрим кодирование GIF с потерями. Giflossy — форк Gifsicle, который поддерживает флаг -lossy и сжимает анимацию на 60−65%. На его основе сделан хороший инструмент Gifify. Неанимированные GIF преобразуйте в формат PNG или WebP.

Для получения дополнительной информации см. «Книгу GIF» от Rigor.
Минимизировать файлы SVG — значит удалить всё лишнее. Как правило, SVG из редактора содержит много избыточной информации (метаданные, комментарии, скрытые слои и так далее). Зачастую её можно безопасно удалить или свести к минимуму, не влияя на визуальный результат.


В сервисе SVGOMG от Джейка Арчибальда можно выбрать разные способы оптимизации с мгновенным просмотром результата

Некоторые общие правила оптимизации SVG (SVGO)

  • Минифицируйте файлы SVG и сжимайте в gzip, ведь SVG — это просто текстовые ресурсы на XML, такие как CSS, HTML и JavaScript. Для повышения производительности их следует минимизировать и сжать.
  • Вместо путей используйте стандартные формы SVG, такие как <rect>, <circle>, <ellipse>, <line> и <polygon>. Это уменьшит объём необходимой разметки и объём кода для парсинга и растеризации в браузере.
  • Если необходимо использовать пути, попробуйте уменьшить их. Упростите и объедините кривые и пути, где возможно. Инструмент simplify в Illustrator хорошо удаляет лишние точки даже в сложных работах, сглаживая неровности.
  • Избегайте групп. Если не можете, попробуйте упростить их.
  • Удалите невидимые слои.
  • Избегайте эффектов Photoshop и Illustrator. Они могут сконвертироваться в большие растровые изображения.
  • Внимательно проверьте наличие встроенных растровых изображений, которые не подходят для SVG.
  • Используйте инструмент для оптимизации SVG, здесь незаменим веб-интерфейс SVGOMG для SVGO. Если используете Sketch, то отличный плагин Sketch для SVGO уменьшает размер файла при экспорте.


Эффективность SVGO в режиме высокой точности (−29% от размера оригинального файла) и низкой точности (−38%)

Он уменьшает размер файла, понижая точность чисел в definitions. SVGO — инструмент оптимизации SVG на Node. Но будьте очень осторожны, потому что снижение точности может визуально повлиять на формы изображения. Каждая цифра после точки — лишний байт, поэтому изменение точности (количества цифр) сильно влияет на размер файла.

Посмотрите, как с понижением точности искажается блик на ракете
Важно отметить: хотя SVGO преуспел в предыдущем примере без чрезмерного упрощения путей и форм, часто случается иначе.

SVGO из командной строки:

SVGO можно установить как CLI, если вы предпочитаете командную строку:

npm i -g svgo

Оптимизация SVG-файла:

svgo input.svg -o output.svg

Поддерживаются все возможные параметры, включая настройку точности с плавающей точкой:

svgo input.svg --precision=1 -o output.svg

readme для полного списка поддерживаемых параметров. См.

Не забудьте сжать SVG!

Текстовый формат будет очень хорошо сжиматься (~50% от исходника). Кроме того, не забудьте зазиповать файлы SVG или выдавать их по протоколу Brotli.

Когда Google выпустила новый логотип, мы объявили, что его минимальная версия занимает всего 305 байт.

Есть много продвинутых трюков, чтобы ещё сильнее ужать файл (вплоть до 146 байт)!

SVG-спрайты

SVG отлично подходит для иконок, предлагая визуализацию в виде спрайта без изворотливых обходных путей, необходимых для шрифтов. У него лучший контроль стилей CSS, чем в шрифтах (свойства SVG stroke), лучший контроль позиционирования (нет необходимости заморачиваться с псевдоэлементами и display) и SVG гораздо лучше поддерживается в браузерах.

Стоит изучить практичные советы от Уны Кравец, как использовать gulp-svg-sprite в рабочем процессе. Инструменты вроде svg-sprite и IcoMoon автоматизируют объединение SVG в спрайты, которые можно использовать в CSS Sprite, Symbol Sprite или Stacked Sprite. Сара Судеин в своём блоге описывает переход от шрифтов для иконок к SVG.

Дополнительные материалы

Советы Сары Соуэйдан по оптимизации выдачи SVG и «Практическая книга по SVG» Криса Койера превосходны. Я нашёл очень полезными статьи Андреаса Ларсена об оптимизации SVG (часть 1, часть 2). Могу также порекомендовать статью «Подготовка и экспорт значков SVG в Sketch».
Сжимать изображение всегда рекомендуется из исходника. Повторное пережатие чревато неприятными последствиями. Предположим, вы берете JPEG, который уже сжат с качеством 60. Если повторно сжать его с потерями, он будет выглядеть хуже. Каждый дополнительный раунд сжатия приведёт к дополнительной потере качества — информация удаляется, а артефакты накапливаются. Даже если вы пережимаете с установками высокого качества.

Затем вы не пойдёте на повторное пережатие, потому что любое сжатие файла с потерями будет выглядеть плохо, хотя и уменьшит размер файла. Чтобы избежать этой ловушки, сразу установите минимально приемлемое качество, и получите максимальную экономию с самого начала.

С такой проблемой можно столкнуться, если сохранять (уже сжатые) картинки из социальных сетей и повторно загружать их (с повторным сжатием).
Пример из отличного видео и сопроводительной статьи Джона Снейерса показывает влияние пережатия в разных форматах. Потеря качества нарастает

Вместо сжатия всех значений DCT как есть он ищет близкие значения в диапазоне +1/-1, чтобы сжать их в меньшем количестве бит. MozJPEG (возможно, случайно) более устойчив к такой деградации благодаря треллис-квантованию. FLIF с потерей качества использует хак, похожий на PNG с потерей качества, где перед (повторным) сжатием кодек анализирует данные и решает, что выбросить.

Затем инструменты сборки или компрессоры подготовят сжатую версию, которую вы отдадите пользователям с минимальными потерями в качестве. Исходные файлы храните их в формате без потерь, например, PNG или TIFF, чтобы сохранить максимальное качество.

Все мы отдавали пользователям большие изображения со слишком высоким разрешением. За это приходится платить. Декодирование и изменение размера — ресурсоёмкие операции для браузера на обычном мобильнике. Если отдавать большие изображения, масштабируя их средствами CSS или атрибутами ширины/высоты, то вы увидите, как это повлияет на производительность.

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

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

Без них браузер присваивает изображению наименьшую область-заполнитель, пока не получит достаточное количество байт для определения правильных размеров. Пропуск атрибутов width или height тоже может негативно повлиять на производительность. В этот момент разметку документа приходится обновлять с помощью ресурсоёмкой операции reflow.

Получив изображение, его необходимо декодировать и зачастую изменить размер.
Браузерам нужно совершить несколько шагов, чтобы отрисовать картинку на экране. Эти события можно отследить на временной шкале Chrome DevTools

Если вы не слишком аккуратны, то можете буквально повесить браузер; на низкобюджетных устройствах не так уж сложно довести ситуацию до свопа. Большие изображения также занимают память: примерно по 4 байта на пиксель после декодирования. Таким образом, следите за издержками на декодирование, изменение размера и потребление памяти.

В некоторых случаях оно в 5 и более раз медленнее, чем на десктопе
Декодирование изображений может оказаться невероятно ресурсоёмким на мобильных телефонах среднего и нижнего уровня.

Для многих изображений время декодирования снизилось с от ~400 мс до ~19 мс! При разработке новой мобильной версии Twitter сильно повысил скорость декодирования изображений, установив правильные размеры.


Панель Timeline/Performance в Chrome DevTools показывает время декодирования изображения в Twitter Lite до и после оптимизации

Доставка изображений HiDPI с помощью srcset

Пользователи могут заходить на сайт через разные мобильные и десктопные устройства с экранами высокого разрешения. Соотношение пикселей устройства (DPR) (также называемое «соотношение пикселей CSS») определяет, как CSS должен интерпретировать разрешение экрана. Стандарт DPR создан производителями телефонов, чтобы увеличить разрешение и резкость мобильных экранов, не уменьшая элементы.

На устройства с экранами высокого разрешения отдаются изображения высокой чёткости (с DPR 2×, 3×), а на стандартные экраны — обычные изображения, так как картинки с DPR 2× и 3× значительно тяжелее. Для максимального качества следует отдавать изображения с наиболее подходящим разрешением.


Соотношение пикселей устройства: многие сайты отслеживают DPR популярных устройств через material.io и mydevice.io

Например, взять картинку 2× для мобильного дисплея с DPR 2×. srcset позволяет браузеру выбрать оптимальное изображение для каждого устройства. Браузеры без поддержки srcset могут взять дефолтный src, указанный в теге <img>.

<img srcset="paul-irish-320w.jpg, paul-irish-640w.jpg 2x, paul-irish-960w.jpg 3x" src="paul-irish-960w.jpg" alt="Paul Irish cameo">

CDN для изображений вроде Cloudinary и Imgix поддерживают DPR для выдачи картинки с оптимальным разрешением из одного источника.

Примечание: узнать больше о соотношении пикселей устройства и отзывчивых изображениях можно в этом бесплатном курсе Udacity и руководстве по изображениям на Web Fundamentals.

Напоминаю, что Client Hints — тоже подходящая альтернатива указанию всех возможных DPR и форматов в отзывчивой разметке. Вместо этого соответствующая информация добавляется к HTTP-запросу, чтобы веб-сервер выбрал наиболее подходящий вариант для конкретного экрана.

Художественное преобразование

Хотя выбор правильного разрешения важен, некоторые сайты думают ещё о красоте. Если у пользователя маленький экран, можно обрезать или увеличить масштаб — и отобразить объект иначе, наилучшим образом используя доступное пространство. Хотя художественное преобразование (art direction) выходит за рамки этой статьи, некоторые сервисы вроде Cloudinary предоставляют API-интерфейсы для автоматизации таких задач.

В этом примере характеристики основного объекта на иллюстрации изменяются, чтобы наилучшим образом использовать доступное пространство
Эрик Портис показал отличный пример, как творчески использовать отзывчивые изображения.

Цвет можно рассматривать минимум с трёх перспектив: биология, физика и печать. В биологии цвет — феномен восприятия. Объекты отражают свет в различных комбинациях длин волн. Световые рецепторы в глазах переводят эти волны в ощущение цвета. В физике важны частоты волн и энергия (яркость). Печать — это больше о цветовом охвате, красках и художественных моделях.

К сожалению, это не так. В идеале, все экраны и веб-браузеры в мире должны в точности одинаково отображать цвет. Управление цветом позволяет достичь компромисса в отображении цветов с помощью цветовых моделей, пространств и профилей.

Цветовые модели

Цветовые модели — это система для создания полного спектра из меньшего набора основных цветов. Есть различные типы цветовых пространств с разными параметрами для управления цветами. В некоторых пространствах меньше управляющих параметров, чем в других — например, для всех оттенков серого достаточно одного параметра яркости между чёрным и белым.

Аддитивные цветовые модели типа RGB отображают цвет свечением, а субтрактивные типа CMYK — отражением (вычитанием). Два распространённых типа цветовых моделей — аддитивные и субтрактивные.

CMYK (циан, маджента, жёлтый и чёрный) работает чернилами разного цвета, отнимая часть белого спектра бумаги
В RGB красный, зелёный и синий свет добавляются в различных сочетаниях для получения широкого спектра цветов.

Статья «Понятие цветовых моделей и систем цвета» хорошо описывает другие цветовые модели и режимы, такие как HSL, HSV и LAB.

Цветовые пространства — это определённый диапазон цветов, которые можно отобразить для данного изображения. Например, в изображении до 16,7 миллиона цветов, а различные цветовые пространства позволяют сузить или расширить этот диапазон. Некоторые разработчики считают, что цветовые модели и цветовые пространства — это одно и то же.

Это небольшое цветовое пространство, которое обычно считают наименьшим общим знаменателем и самым безопасным вариантом для управления цветом в браузерах. sRGB разработан на основе RGB как стандарт для интернета. Другие цветовые пространства (например, Adobe RGB или ProPhoto RGB, используемые в Photoshop и Lightroom) содержат более разнообразные цвета, но поскольку sRGB распространён в браузерах, играх и мониторах, обычно используют именно его.


Визуализация гаммы — диапазона цветов в цветовом пространстве

16-битные картинки спосбоны отображать триллионы цветов. В цветовых пространствах используется три канала (красный, зелёный и синий), в каждом по 255 цветов в 8-битном режиме, что даёт 16,7 миллиона цветов.

Невероятно трудно проиллюстрировать эту концепцию, если ваш экран показывает только цвета sRGB.
Сравнение sRGB, Adobe RGB и ProPhoto RGB на изображении с Yardstick. При сравнении обычной фотографии в sRGB и широкой гамме всё будет одинаково, кроме самых насыщенных «сочных» цветов

sRGB примерно на 20% меньше, чем Adobe RGB, ProPhoto RGB примерно на 50% шире, чем Adobe RGB. Цветовые пространства отличаются своей гаммой (диапазон цветов, которые они могут воспроизводить с оттенками), спектром и гамма-кривой. Фотографии выше взяты с Clipping Path.

Такие типы дисплеев становятся всё более распространёнными. Широкая гамма (wide-gamut) — это термин, означающий цветовые пространства шире sRGB. При сохранении для веба в Photoshop используйте опцию преобразования в sRGB, если только не рассчитываете на дисплеи с широкой цветовой гаммой. Тем не менее, многие цифровые дисплеи по-прежнему просто не способны отображать цветовые профили, которые значительно лучше sRGB.

Оно меньше, цветовых пространств в большинство камер и может привести к потере информации. Примечание: При работе с оригинальными фотографиями не используйте sRGB в качестве основного цветового пространства. Вместо этого работайте с широким цветовым пространством (например, ProPhoto RGB), в конвертируйте в sRGB только при экспорте для интернета.

Есть ли случаи, когда широкая гамма имеет смысл для веб-контента?

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

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

Гамма-коррекция и сжатие

Гамма-коррекция (или просто гамма) управляет общей яркостью изображения. Изменение гаммы также может изменить соотношение красного и зелёного цветов. Изображения без гамма-коррекции часто выглядят блеклыми или тёмными.

Это позволяет сжать полезные уровни яркости в меньшем количестве бит (8, а не 12 или 16). В видео и компьютерной графике гамма используется для сжатия, аналогично сжатию данных. Представление цветов в их истинной физической форме было бы расточительным при кодировании для человеческого глаза. Человеческое восприятие яркости нелинейно пропорционально физическому количеству света. Гамма-сжатие (gamma compression) используется для кодирования яркости в масштабе, более близком человеческому восприятию.

Представьте, что вы находитесь в тёмной комнате с одной свечой. С гамма-сжатием полезная шкала яркости умещается в 8 бит точности (0−255 в большинством цветов RGB), потому что единицы яркости кодируются нелинейно. Добавьте третью свечу, и комната станет ещё ярче. Зажгите вторую — и заметите значительное увеличение яркости. Зажгите 101-ю, 102-ю свечи — и вы не заметите никаких изменений. А теперь представьте себя в комнате с сотней свечей.

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

Примечание: Гамма-коррекция или сжатие здесь отличаются от гамма-кривых в «Фотошопе», правильное гамма-сжатие ни на что не похоже.

Цветовые профили

Цветовой профиль — это информация, описывающая цветовое пространство устройства. Он используется для преобразования между различными цветовыми пространствами. Задача профилей — чтобы изображения были максимально похожи на всех типах экранов и носителей.

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

Поэтому внедрение цифровых профилей в изображения может быть ограничено. Примечание: Цветовые профили некоторых мониторов аналогичны sRGB, так что они не смогут отобразить цвета из более широкой гаммы. Учитывайте особенности своей целевой аудитории.

Встроенные цветовые профили также значительно увеличивают размер изображений (иногда на 100 КБ и больше), поэтому будьте осторожны. Инструменты вроде ImageOptim автоматически удаляют все цветовые профили, какие найдут. Если профиль ICC удалён, браузер начнёт отображать картинку в цветовом пространстве вашего монитора, что может привести к изменению насыщенности и контраста. Так что есть смысл поискать компромисс для каждого конкретного случая.

На сайте Nine Degrees Below отличная подборка ресурсов по управлению цветовыми профилями ICC, если вам нужна дополнительная информация.

Цветовые профили и браузеры

В прежних версиях Chrome не было особой поддержки управления цветом, но ситуацию исправили в 2017 году, внедрив функцию Color Correct Rendering. Если профиль дисплея отличается от sRGB (последние MacBook Pro), то он преобразуют цвета из sRGB в профиль дисплея. Это означает, что цвета станут более похожими в разных системах и браузерах. Браузеры Safari, Edge и Firefox тоже учитывают профили ICC, поэтому изображения с разными профилями теперь отображаются корректно, независимо от того, у вас дисплей с широкой цветовой гаммой или нет.

Примечание: Отличное руководство о разнообразных способах использования цвета в вебе — «Справочник нерда по цвету в интернете» Сары Дразнер.

У спрайтов изображений (или CSS-спрайтов) долгая история, они поддерживаются всеми браузерами и были популярным способом уменьшить количество загружаемых картинок путём объединения их в одно более крупное изображение, которое нарезается на части.


Спрайты изображений по-прежнему широко используются на крупных сайтах в продакшне, включая главную страницу Google

Это имело ряд преимуществ, но требовало аккуратности из-за проблемы с инвалидацией кэша — изменения любой небольшой части спрайта приведут к инвалидации всего изображения в кэше. По стандарту HTTP/1.x некоторые применяли спрайты для уменьшения количества HTTP-запросов.

Поскольку стало возможно отправлять много запросов в одном соединении, то лучше загружать картинки по отдельности. Сейчас разбиение на спрайты противоречит рекомендациям HTTP/2. Оцените варианты для своей ситуации.

Ленивая (отложенная) загрузка — это практика повышения производительности, когда загрузка изображений в браузер задерживается до тех пор, пока реально не понадобится пользователю. Например, картинки загружаются асинхронно при прокрутке страницы. Это может экономить трафик дополнительно к сжатию изображений.

Но остальные в этот момент ещё не видны. Попадающие на экран картинки загружаются сразу. Она происходит только если и когда пользователь прокручивает страницу вниз. Их следует загружать не сразу, а позже — это и есть ленивая загрузка.

Вместо этого используется JavaScript. Ленивая загрузка пока не поддерживается самими браузерами (хотя в прошлом такое обсуждалось).

Почему полезна отложенная загрузка?

У неё много преимуществ:

  • Экономия трафика. Вы загружаете минимальное количество ресурсов. Это всегда хорошо, особенно на смартфонах с тарифами на трафик.
  • Экономия заряда батареи. Меньше нагрузки на браузер — меньше расход батареи.
  • Увеличение скорость загрузки. Сокращение времени загрузки тяжёлого сайта с обилием графики с нескольких секунд почти до нуля дорогого стоит. Фактически, эта разница может сохранить посетителя на сайте, а не добавить единичку в статистику отказов.

Впрочем, как и с другими инструментами, с большой силой приходит большая ответственность.

Не применяйте её для главной картинки на странице. Избегайте отложенной загрузки изображений в области видимости. Используйте её для длинных списков (например, продуктов или пользовательских аватар). Она убивает предзагрузку и прогрессивную загрузку, а JavaScript генерирует лишнюю работу для браузера. Ленивая загрузка в области видимости может замедлить загрузку как технически, так и для человеческого восприятия.

Одна из рекомендаций — начинать ленивую загрузку следующих изображений сразу после того, как на экране отобразилось предыдущее, независимо от взаимодействия с пользователем. Будьте очень осторожны с ленивой загрузкой изображений при прокрутке. Если ждать непосредственно события прокрутки, то пользователь может увидеть заполнители вместо картинок или получить картинки до скроллинга на них.

Кто использует отложенную загрузку?

Ленивую загрузку применяет большинство крупных сайтов с большим количеством изображений. Например, Medium и Pinterest.


Пример превью с гауссовым размытием иллюстраций на Medium

На некоторых сайтах (например, Medium) для предварительного просмотра отображается небольшая размытая картинка (около 100 байт), которое после отложенной загрузки превращается в иллюстрацию нормального качества.

Перес рассказал, как реализовать эффект Medium с помощью CSS-фильтров. Хосе М. Facebook тоже описывал свой знаменитый подход с 200-байтовыми заполнителями для заглавных фотографий. Он экспериментировал с разными графическими форматами. Если вы пользуетесь Webpack, то LQIP loader поможет автоматизировать некоторые из этих процедур.

Почти всегда вы увидите, что сайт загружает только несколько картинок с полным разрешением, а остальное — заполнители. Чтобы увидеть ленивую загрузку, достаточно открыть любимый каталог качественных фотографий, а затем прокрутить страницу вниз. Это ленивая загрузка. По мере прокрутки заполнители заменяются изображениями в полном разрешении.

Её предложил Тобиас Балдауф в своём инструменте SQIP. В последнее время получила распространение новая техника векторных, а не растровых заполнителей. Затем SVG оптимизируется с помощью SVGO — и накладывается фильтр гауссова размытия. Там утилита Primitive генерирует SVG-превью из нескольких простых форм, примерные совпадающих с основными чертами изображения. Очевидно, можно комбинировать ленивую загрузку и предварительный просмотр изображений в низком качестве. В результате получается заполнитель SVG размером всего 800−1000 байт, который выглядит чётким на любых экранах и даёт осмысленное представление, что находится на реальной картинке.

Как применить отложенную загрузку?

Для отложенной загрузки есть ряд методов и плагинов. Я рекомендую lazysizes Александра Фаркаса из-за его достойной производительности, функциональности, дополнительной интеграции с Intersection Observer и поддержки плагинов.

Что умеет Lazysizes?

Lazysizes — это библиотека JavaScript, она не требует настройки. Просто скачайте минифицированный файл js и включите его в веб-страницу.

Ниже пример кода из файла README:

Добавьте класс 'lazyload’ к изображениям/фреймам в сочетании с атрибутом data-src и/или data-srcset.

Дополнительно можно добавить атрибут src с изображением низкого качества:

<!-- non-responsive: -->
<img data-src="image.jpg" class="lazyload" /> <!-- responsive example with automatic sizes calculation: -->
<img data-sizes="auto" data-src="image2.jpg" data-srcset="image1.jpg 300w, image2.jpg 600w, image3.jpg 900w" class="lazyload" /> <!-- iframe example --> <iframe frameborder="0" class="lazyload" allowfullscreen="" data-src="//www.youtube.com/embed/ZfV-aYdU4uE">
</iframe>

Для веб-версии этой книги я связал Lazysizes с Cloudinary (хотя вы можете использовать любую альтернативу). Это позволяет свободно и с минимальными усилиями экспериментировать с различными масштабами, качеством, форматами и независимо от того, нужна ли прогрессивная загрузка:

Особенности Lazysizes:

  • Автоматически определяет изменения в видимости текущих и будущих элементов ленивой загрузки
  • Поддержка стандартных отзывчивых изображений (picture и srcset)
  • Автоматический расчет размеров и алиасы для медиазапросов
  • Работает с сотнями изображений/фреймов на CSS, в насыщенных скриптами страницах и веб-приложениях
  • Расширяемость: поддерживает плагины
  • Лёгкое, но зрелое решение
  • Улучшение SEO: не скрывает изображения/активы от краулеров

Другие способы ленивой загрузки

Lazysizes — не единственный вариант. Есть и другие библиотеки:

В чём недостатки ленивой загрузки?

  • Программы чтения с экрана, некоторые поисковые боты и пользователи с отключенным JavaScript не увидят изображения, загруженные с помощью JavaScript. Но этого недостатка можно избежать запасным вариантом <noscript>.
  • Прослушивание событий прокрутки может негативно повлиять на производительность скроллинга. Браузер попытается многократно перерисовывать экран (redraw), но грамотные библиотеки отложенной загрузки смогут смягчить этот негативный эффект за счёт дросселирования. Одно из возможных решений — Intersection Observer, который поддерживается в библиотеке lazysizes.

Отложенная загрузка — распространённый способ экономии трафика, снижения затрат и улучшения взаимодействия с пользователем. Оцените, насколько она полезна в вашем случае. Для дополнительной информации см. статьи «Ленивая загрузка изображений» и «Реализация прогрессивной загрузки в Medium».
Старые решения для отзывчивых изображений ошибочно обрабатывали запросы изображений при установке свойства CSS display. Это могло привести к значительному увеличению количества запросов, что является ещё одной причиной, почему предпочтительно использовать и .

Вы когда-нибудь писали запрос media, который в определённых условиях прячет картинку в display:none?

<img src="img.jpg">
<style>
@media (max-width: 640px) { img { display: none; }
}
</style>

Или скрывает изображения с помощью класса display:none?

<style>
.hidden { display: none;
}
</style>
<img src="img.jpg">
<img src=“img-hidden.jpg" class="hidden">

Быстрая проверка в сетевой панели Chrome DevTools показывает, что такие «спрятанные» изображения всё равно загружаются. На самом деле это корректное поведение браузера согласно спецификации встроенных ресурсов.

Помогает ли display:none избежать запроса src?

<div style="display:none"><img src="img.jpg"></div>

Нет. Указанное изображение всё равно будет запрошено. Здесь библиотека не может полагаться на display:none, потому что запрос отправляется раньше, чем JavaScript изменит src.

Помогает ли display:none избежать запроса background: url()?

<div style="display:none"> <div style="background: url(img.jpg)"></div>
</div>

Утвердительный ответ. Фон CSS не извлекается при разборе элемента. Расчёт стилей CSS для дочерних элементов с display:none менее полезен, так как они не влияют на рендеринг документа. Фоновые изображения дочерних элементов не рассчитываются и не загружаются.

Если сомневаетесь, как конкретный браузер обрабатывает запросы изображений, откройте DevTools и проверьте сами. У Джейка Арчибальда есть отличный квест-викторина по ловушкам display:none.

Опять же, где возможно используйте <picture> и <img srcset> вместо того, чтобы полагаться на <display:none>.

Время, потраченное на чтение статей для настройки своего конвейера обработки изображений и его последующей доработки зачастую намного дороже, чем плата за эту услугу. Cloudinary предлагает бесплатный сервис, Imgix даёт бесплатную пробную версию, есть свободная альтернатива Thumbor, так что вариантов немало.

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

Свой сервер или CDN?

Манипуляции с изображениями — специфическая тема. Тут всё постоянно меняется, поэтому начнём с цитаты опытного специалиста, а затем продолжим.

Сервисы вроде Cloudinary [или Imgix, прим. «Если ваш продукт сам по себе не связан с обработкой изображений, то не делайте это самостоятельно. И если вы беспокоитесь о цене, подумайте, во сколько обойдутся разработка и обслуживание, а также хостинг, хранение и доставка» — Крис Гмыр авт.] справятся намного лучше и эффективнее.

Рассмотрим два таких сервиса — как они соответствуют списку упомянутых задач. На данный момент мы склонны согласиться, что лучше использовать CDN для обработки изображений.

Cloudinary и Imgix

Cloudinary и Imgix — хорошо известные CDN для обработки изображений. Их используют сотни тысяч разработчиков и компаний по всему миру, включая Netflix и Red Bull.

Основное

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

Imgix предлагает бесплатную пробную версию, это почти то же самое, что и бесплатный тариф. Второе: у каждого сервиса многоуровневую тарифный план: У Cloudinary бесплатный тариф, у Imgix недорогой стартовый план.

Разработчики могут программно подключаться к CDN и автоматизировать процесс. Третье: у обоих сервисов есть API. Доступны клиентские библиотеки, плагины для фреймворков и документация по API, хотя некоторые опции доступны только на дорогих тарифах.

Перейдём к обработке изображений

Ограничим дискуссию статичными изображениями. Cloudinary и Imgix предлагают широкий спектр методов обработки изображений. В стандартных и бесплатных тарифах оба поддерживают базовые функции: сжатие, изменение размера, обрезка, генерация уменьшенных копий.

Чтобы активировать эту опцию, поставьте соответствующий значок в «Дополнительных параметрах» или используйте флаг fl_progressive
Cloudinary Media Library: По умолчанию Cloudinary выдаёт обычные, а не прогрессивные JPEG.

У Imgix более 100 операций обработки изображений. Cloudinary называет семь широких категорий преобразования, в общей сложности 48 подкатегорий.

Что происходит по умолчанию?

Cloudinary по умолчанию выполняет следующие оптимизации:

  • Кодирование в JPEG с помощью MozJPEG (выбрали вместо Guetzli по умолчанию).
  • Очистка от метаданных (исходное изображение остаётся нетронутым). Чтобы изменить это поведение и отдавать картинки с метаданными, добавьте флаг keep_iptc.
  • Возможность генерации WebP, GIF, JPEG и JPEG-XR с автоматическим качеством. Чтобы изменить настройки по умолчанию, задайте параметр качества вручную.
  • Оптимизация размера файлов с минимальным влиянием на качество при генерации PNG, JPEG или GIF.

Imgix по умолчанию не запускает такие оптимизации, как Cloudinary, но позволяет установить дефолтное качество. В Imgix автоматические параметры помогают автоматизировать базовый уровень оптимизации в каталоге изображений.

В настоящее время используется четыре метода:

  • Сжатие
  • Визуальное улучшение
  • Преобразование форматов файлов
  • Удаление эффекта красных глаз

Imgix поддерживает следующие форматы изображений: JPEG, JPEG2000, PNG, GIF, анимированный GIF, TIFF, BMP, ICNS, ICO, PDF, PCT, PSD, AI.

Cloudinary поддерживает такие форматы: JPEG, JPEG 2000, JPEG XR, PNG, GIF, анимированный GIF, WebP, анимированный WebP, BMP, TIFF, ICO, PDF, EPS, PSD, SVG, AI, DjVu, FLIF, TARGA.

Что насчёт производительности?

Производительность CDN в основном зависит от задержки и скорости.

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

Скорость влияет на время загрузки страницы, а это одна из самых важных метрик для пользователей и конверсии. У обоих CDN широкое покрытие и быстрые серверы, за счёт чего снижается задержка и увеличивается скорость загрузки.

Что же лучше?

У Cloudinary около 160 000 клиентов, включая Netflix, eBay и Dropbox. Imgix не сообщает количество пользователей, но оно меньше, чем у Cloudinary. Тем не менее, база Imgix включает в себя таких тяжеловесов как Kickstarter, Exposure, unsplash и Eventbrite.

Многое зависит от того, как вы хотите обработать изображение (это займёт разное время), какой размер и разрешение нужны в итоге. В обработке изображений столько параметров не поддаются объективной оценке, что затруднительно сравнить производительность двух служб. В конце концов, самым важным фактором для вас может оказаться стоимость.

Тяжёлый сайт с большим трафиком может платить сотни долларов в месяц на CDN. CDN стоят денег. Но если вы не делаете ничего необычного, то особых проблем не возникнет. Необходим определённый уровень знаний и навыков программирования, чтобы получить максимальную отдачу от этих услуг.

Вывод

Если вы сейчас отдаёте изображения с собственного сервера или планируете так поступить, возможно, вам следует подумать о CDN.
Ресурсы могут задавать правила кэширования через HTTP-заголовки кэша. В частности, Cache-Control определяет, кто и как долго должен кэшировать ответы.

Наилучшая стратегия для них — агрессивное кэширование. Большинство изображений — статические ресурсы, которые не изменятся в будущем.

Такое агрессивное кэширование хорошо работает для большинства изображений, особенно для долгоживущих, таких как аватары и картинки в заголовках страниц. При настройке HTTP-заголовков кэширования, установите Cache-Control со сроком max-age на год (например, Cache-Control:public; max-age=31536000).

Проблему можно обойти с помощью session_cache_limiter('public'), указав public и max-age=. Примечание: если вы отдаёте изображения с помощью PHP, то кэширование отключится из-за дефолтной настройки session_cache_limiter. Как вариант, отключение опции и настройка кастомных заголовков управления кэшем.

Критические ресурсы можно предварительно загрузить с помощью <link rel=preload>.

Это повышает приоритет запросов на ресурсы, которые в противном случае будут обнаружены только позже во время парсинга. <link rel=preload> — это декларативная загрузка, которая заставляет браузер отправить запрос на ресурс, не блокируя событие onload для документа.

Для предварительной загрузки изображений значение as указывается как image:

<link rel="preload" as="image" href="logo.jpg"/>

Таким способом оптимизируется загрузка ресурсов для <img>, <picture>, srcset и SVG.

Примечание: <link rel=preload> поддерживается в Chrome и браузерах на движке Blink, таких как Opera и Safari Tech Preview, а также реализована в Firefox.

Такие сайты, как Philips, Flipkart и Xerox, используют <link rel=preload> для предварительной загрузки своих логотипов (часто используемых в начале документа). Kayak тоже применяет предварительную загрузку, чтобы главная картинка в заголовке загружалось максимально быстро.

Что такое заголовок Link preload?

Предзагрузка ссылки задаётся тегом HTML или в заголовке HTTP Link Header. В любом случае ссылка указывает браузеру начать загрузку ресурса в кэш памяти, потому что страница с высокой степенью вероятности ожидает этот ресурс и нельзя ждать, пока сканер предварительной загрузки или синтаксический анализатор его обнаружит.

Заголовок для изображений будет выглядеть следующим образом:

Link: <https://example.com/logo-hires.jpg>; rel=preload; as=image

Когда Financial Times представила такой заголовок на своём сайте, пользователи стали открывать контент на 1 секунду быстрее:

Сравнение для Moto G4 на канале 3G по тесту WebPageTest до и после оптимизации
Снизу: с <link rel=preload>, сверху: без.

Аналогичным образом и Википедия ускорила загрузку «до логотипа», как описывается в их исследовании.

Какие подводные камни в этой оптимизации?

Нужно быть уверенным, что предварительная загрузка именно этого ресурса абсолютно необходима, потому что он сдвигает остальной контент в конец очереди. Может быть следует сосредоточить усилия на другом контенте?

Важно избегать rel=preload для предварительной загрузки изображений без широкой поддержки в браузерах (например, WebP) и избегать применения в отзывчивых изображениях, определённых в srcset, где источник картинки зависит от типа устройства.

Для дополнительной информации ознакомьтесь со статьями «Предзагрузка и приоритеты в Chrome» и «Предварительная загрузка: для чего она хорошо подходит?»

Бюджет производительности — это максимальный лимит, который разработчики стараются не превышать. Например, «не больше 200 КБ картинок на одной странице» или «пользовательский интерфейс должен загружаться быстрее, чем за 3 секунды». Когда бюджет не выполняется — изучите, почему это происходит и как исправить ситуацию.

Когда дизайн или бизнес-решение влияет на производительность, сверяйтесь с бюджетом. Бюджеты помогают обсуждать результаты работы. Если изменение не вписывается в бюджет, это основание для того, чтобы отложить или пересмотреть его.

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

Как только определён бюджет по размеру изображений, SpeedCurve начинает мониторинг и предупреждает о превышении:

Это полезно, поскольку бюджет по размеру картинок для десктопного ПК по WiFi может сильно отличаться от бюджета для мобильников. Calibre предлагает установку бюджета для каждого класса устройств.

В конечном счёте выбор стратегии оптимизации изображений сводится к типам изображений, которые вы отдаёте пользователям, и разумному набору критериев оценки на выбор. Это может быть SSIM или Butteraugli, а на маленьком наборе иллюстраций можно довериться собственному глазу: что выглядит лучше, а что хуже.

Вот мои заключительные рекомендации:

Если вы не можете отдавать изображения в разных форматах, в зависимости от поддержки в браузере:

  • Guetzli + jpegtran из MozJPEG хорошо оптимизируют при качестве JPEG более 90.
    • Для веба качество q=90 слишком расточительно. Для обычных картинок достаточно q=80, а для DPR 2× даже q=50. Поскольку Guetzli не выходит на такой низкий уровень, то для веба можно использовать MozJPEG.
    • Корнель Лесински недавно улучшил команду cjpeg в mozjpeg, добавив крошечный профиль sRGB, чтобы помочь Chrome отображать естественный цвет на дисплеях с широкой цветовой гаммой.
  • PNG pngquant + advpng обеспечивает довольно хорошее соотношение скорости/сжатия.

Если вы можете отдавать изображения в разных форматах, в зависимости от поддержки в браузере, используя , заголовок Accept или Picturefill:

  • Отдавайте WebP для браузеров, которые его поддерживают
    • Создавайте WebP из оригинальных изображений 100% качества. Иначе вы будете отдавать в браузеры картинки худшего качества и большего объёма с искажениями JPEG и искажениями WebP! Если сжимаете исходные изображения кодеком WebP, то искажения будут менее заметны, а уровень сжатия выше.
    • Настройки по умолчанию WebP -m 4 -q 75 хороши для большинства случаев как оптимальное соотношение скорости и степени сжатия.
    • У WebP есть специальный режим сжатия без потерь (-m 6 -q 100), который уменьшает файлы, изучив все сочетания параметров. Это на порядок медленнее, но стоит того для статических ресурсов.
  • Запасной вариант — Guetzli/MozJPEG для браузеров, которые не поддерживают WebP.

Удачной компрессии!

В книге High Performance Images тоже много отличных советов и нюансов. Примечание: для более практических советов по оптимизации изображений настоятельно рекомендую книгу Web Performance in Action Джереми Вагнера.

  • JPEG XT определяет расширения спецификации JPEG 1992 года. Чтобы гарантировать идеальную совместимость со старым стандартом пришлось уточнить спецификацию 1992 года, а кодек libjpeg-turbo выбран в качестве эталонной реализации (как самый популярный).
  • PIK — это новый графический кодек, за которым стоит следить. Он совместим с JPEG, имеет более эффективное цветовое пространство и использует преимущества Guetzli. Он декодирует на 33% медленнее JPEG, но удаляет из файлов на 54% больше лишней информации, чем libjpeg. Он быстрее в Guetzli в декодировании. Исследование психовизуального сходства современных кодеков показало, что PIK намного превосходит альтернативы. К сожалению, кодек пока на ранних стадиях разработки, и кодирование пока неприемлемо медленно (сравнение проводилось в августе 2017 года).
  • Для оптимизации изображений часто рекомендуют ImageMagick. Это хороший инструмент, но результат его работы обычно нуждается в дополнительной оптимизации, а другие инструменты справляются лучше. Мы рекомендуем libvips, хотя это более низкоуровневый инструмент и более требователен к технической квалификации пользователя. У ImageMagick также периодически находили уязвимости в безопасности, о которых желательно знать.
  • Blink (движок рендеринга в Chrome) декодирует изображения вне основного потока. Перенос декодера в поток компоновщика освобождает основной поток для работы над другими задачами. Мы называем это отложенным декодированием. Но даже в этом случае работа декодера занимает критический путь для вывода фрейма на экран, поэтому он всё ещё может вызвать подтормаживание и рывки анимации. img.decode() API должен устранить эту проблему.

Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Не позволяйте 3D-принтеру лениться

Наверное, у каждого из нас есть гаджет или устройство, которые мы не используем: тренажёр, плеер, кухонный инвентарь, всякие странные штуки для автомобиля, шнуры, хабы и проч. Лежат они, новенькие, с гарантийниками и годами ждут своего часа, которому чаще всего уже ...

[Перевод] Знакомимся с альфа-версией снапшотов томов в Kubernetes

перев.: оригинальная статья была недавно опубликована в блоге Kubernetes и написана сотрудниками компаний Google и Huawei (Jing Xu, Xing Yang, Saad Ali), активную деятельность которых вы непременно видели в GitHub'е проекта, если когда-либо интересовались фичами и проблемами K8s, связанными с ...