Изображение для верхней части сайта
Речь идёт о подготовке изображения, рассчитанного на использовании в верхней правой части сайта jamstackconf.com. Мы, в маркетинговой команде Netlify, используем Figma. Первая моя попытка экспорта этого изображения для использования его на сайте оказалась далеко не самой удачной.
Попытка №1: SVG
Вот на какие примерные размеры изображения я вышел, экспортировав материалы в формате SVG:
- 10,1 Мб — исходный SVG-файл, экспортированный из Figma.
- 9,9 Мб — SVG-файл, оптимизированный с помощью инструмента SVGOMG.
Теперь я знаю, что это — размеры несжатых файлов (до применения к ним алгоритмов сжатия GZIP/Brotli). Но я уверен, что никто не станет со мной спорить о том, что изображение размером 9,9 Мб, пусть и оптимизированное, слишком велико даже для самого старательного алгоритма сжатия (Уточнение: после GZIP-сжатия 9,9 Мб превратились в 7,36 Мб). Учитывая то, что в этом SVG-файле имеется очень много встроенных растровых изображений, с помощью одного лишь SVGOMG как следует этот файл не сжать. Попробуем перейти к растровому изображению и узнать о том, насколько далеко в деле оптимизации изображений нас это может завести.
Попытка №2: PNG
- 1,2 Мб — исходный PNG-файл, экспортированный из Figma.
Вы все знаете меня достаточно хорошо для того чтобы понять, что я не размещу картинку размером 1,2 Мб в очень важном месте страницы. Поэтому я решил заняться оптимизацией. Тут важно учитывать то, что мне надо было сохранить канал прозрачности. В результате, если изменится фоновый цвет страницы, не придётся снова оптимизировать изображение. Этот факт означает, что мы сразу же отказываемся от формата JPEG.
▍ImageOptim
- 831 Кб — PNG-файл, оптимизированный с помощью ImageOptim.
Меня впечатлило то, что, после буквально одного движения мыши, ImageOptim убрал примерно 400 Кб данных из моего изображения. Но итоговые 831 Кб — это всё ещё слишком много.
▍Squoosh
- 376 Кб — PNG-файл, оптимизированный с помощью Squoosh (с применением уменьшенной цветовой палитры, состоящей из 256 цветов).
Вот это уже похоже на что-то приличное. Опция уменьшения цветовой палитры Squoosh (Reduce palette) даёт огромный выигрыш в размерах готового изображения. Ещё я немного поэкспериментировал с параметрами формата AVIF в Squoosh, но формат PNG, всё равно, оказался лучше (Уточнение от 27 августа: обратите внимание на новый раздел с заголовком «Попытка №4: AVIF»).
Попытка №3: WebP
- 152 Кб — WebP-файл, оптимизированный в Squoosh (сжатие без потерь, цветовая палитра уменьшена до 256 цветов).
Поразительная экономия! И этот вариант предусматривает использование тега
<picture>
для прогрессивного перехода с PNG на WebP. Многие могут решить, что этот результат уже «достаточно хорош», но всё то, ради чего я писал этот материал, ещё впереди (и то, что получилось, получилось, и правда, очень хорошо).Попытка №4: AVIF
- 168 Кб — AVIF-файл, оптимизированный в Squoosh (полная цветовая палитра).
Уточнение от 27 августа: Джейк Арчибальд дал мне хороший совет, который заключался в том, чтобы снова попробовать формат AVIF (но в режиме сжатия с потерями), не уменьшая цветовую палитру. Полагаю, что это — очень хорошая идея! Уменьшение цветовой палитры (хотя и даёт значительную экономию размера файла) определённым образом сказывается на готовом изображении. Моей неофициальной целью было получение AVIF-изображения как можно более высокого качества и сохранение при этом размеров файла на уровне WebP-версии с уменьшенной цветовой палитрой.
Вот — отличный материал Джейка про AVIF.
Этот вариант изображения получен при использовании следующих настроек Squoosh:
- Lossless: выключено.
- Quality: 45.
- Subsample Chroma: выключено.
- Effort: 6.
Победитель: два отдельных слоя: SVG + AVIF/WebP/PNG
- 74 Кб + 4,2 Кб — оптимизированные SVG-файл и AVIF/WebP/PNG-файл
Если выделить те части изображения, которые хорошо описываются векторными инструментами (градиенты, линии и прочее подобное), и поместить их в SVG-изображение, а всё остальное сохранить в растровом формате, мы можем добиться даже лучших результатов. Пользуясь этим подходом, я, правда, сделал не всё, что было возможно. А именно, перенёс на векторный слой не всё, что можно было туда перенести. Возможно, кто-то решит, пользуясь таким подходом, оставить больше фрагментов изображения на переднем плане, например, на тот случай, если кто-нибудь захочет распечатать страницу (ну — это если кто-то до сих пор выводит веб-страницы на принтерах).
Два слоя изображения
Используя растровый слой как изображение переднего плана, а вспомогательное векторное изображение — в виде того, что задаётся в CSS-свойстве
background-image
, мы можем скомбинировать эти изображения. Можно даже вернуть оптимизированное растровое изображение обратно в формат SVG, в виде Data URI, внедрённого в <image>
, но я так делать не стал.Итоговые результаты
Тут показаны результаты вышеописанных экспериментов. Полагаю, то, что удалось прийти от исходного изображения размером более 10 Мб к изображению размером в 78 Кб, это — не так уж и плохо. Экономия рассчитана в сравнении с предыдущей попыткой.
Метод | Размер | Экономия |
Исходный SVG | 10,06 Мб | |
SVG, оптимизированный с помощью SVGOMG | 9,92 Мб | -0,14 Мб |
PNG | 1,16 Мб | -8,76 Мб |
PNG, оптимизированный с помощью ImageOptim | 831 Кб | -329 Кб |
PNG, оптимизированный с помощью Squoosh (уменьшенная палитра) | 376 Кб | -455 Кб |
WebP, оптимизированный с помощью Squoosh (уменьшенная палитра) | 152 Кб | -224 Кб |
AVIF, оптимизированный с помощью Squoosh (полная палитра) | 168 Кб | +16 Кб |
Два слоя: SVG (SVGOMG) и AVIF/WebP/PNG (Squoosh) | 78 Кб | -90 Кб |
Как вы оптимизируете изображения для своих веб-проектов?
Комментарии (17)
i360u
26.09.2021 19:36+4Какой ерундой люди готовы заниматься, лишь бы не открывать SVG в текстовом редакторе...
Moskus
26.09.2021 22:25Справедливости ради, это ещё и отличный пример (независимо от технической сложности задачи), чего не стоит делать с точки зрения дизайна. Все эти микро-физиономии людей, которых никто не знает, снятые веб-камерой во время zoom-встречи не должны были появиться в макете вообще.
mSnus
27.09.2021 05:12+1Сохранили бы в JPEG и не мучились. Изменится фон сайта? Ну, придётся переделать JPEG, займёт минуту.
rexen
28.09.2021 10:08Кстати, с нынешней модой на light/dark - темы сайтов иногда так и приходится делать - по два набора оформительской графики - для тёмной и для светлой схемы.
SquareRootOfZero
27.09.2021 09:28+2Давно делаю что-то подобное для подписей к картинкам. Я не веб-дизайнер и не мастерю сайты, но иногда бывает нужно взять фотографию и где-то понадписывать текста, подрисовать тонких аккуратных стрелочек и вот этого всего. Если результат сохранить в jpeg, текст и линии превращаются в говно, если в png — размер опухает в десятки раз. Остановился на формате («сам придумал») SVG, когда в одном слое jpeg-фотография, в слое поверх — png с текстом и стрелками (можно бы, наверное, оставить их в векторном представлении, но для простоты и автоматизации png вполне хватает), оба слоя кодируются в base64 и встраиваются в SVG-файл, результат выглядит как-то так:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <image href="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDABALDA4MCh..."/> <image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA88AAAMrCAYAAAB3Xq..."/> </svg>
Размер файла практически идентичен сумме исходных файлов, процесс изготовления тоже довольно прост (открыл картинку в первом слое, нарисовал подписи во втором слое, удалил первый слой, экспортировал все в png, простеньким самописным скриптом сконвертировал в вышеприведенный SVG (возможно, есть проще способы, без скриптов, но я не дизайнер, у меня Gimp и лапки). Что не радует — это что всякие дефолтные графические просмотрщики такое открывают плохо или не открывают вовсе, и в какое-нибудь корпоративное вики оно тоже не встраивается как изображение — сперва качай файл, потом у себя отдельно открывай браузером.Akon32
27.09.2021 10:20Подобные идеи разделения текста и картинок лежат в основе формата djvu. Но вместо png там - более агрессивные методы сжатия бинарных изображений текста.
И результат - около 60кб на скан страницы А4.
mSnus
28.09.2021 14:16Вообще есть такой универсальный формат - pdf, в нем подобные случаи как раз предусмотрены. Но если для себя -- да, отличное решение.
SquareRootOfZero
28.09.2021 15:06Самый главный вопрос — «универсальный формат pdf» можно вставить в веб-страницу не как что-то инородное, а как обычное изображение, без всех этих вот отдельных встроенных оконцев, виджетов и гаджетов?
И второй вопрос — каким достаточно простым и бесплатным софтом такой pdf можно изготовить? Из того, чем я обычно пользуюсь — Gimp сделал как-то криво, к тому же, файл таки опух со 100 Кб до мегабайта; Inkscape экспортировать в PDF не дает вообще; самому писать скрипт — как-то уныло, в отличие от SVG за пять минут левой ногой не сделаешь.
А чисто для себя-то можно во внутреннем формате любого редактора хранить, да и размер файла не особо важен.
Tenebrius
27.09.2021 10:28Судя по двум последним картинкам (Вектр + Раст), растровую часть тоже вполне можно было перевести в вектр. Там логотипы и текст, а они и так почти всегда в векторном виде.
starcs
28.09.2021 12:00+4Решил провести исследование и скачал эти файлы сайта. Учтем, что у меня не исходники и они уже оптимизированы.
Если открыть .svg файл в Photoshop, то узнаем, что его размер 3721х3721 пикс. Открыв .png - 1786х1786 с прозрачным полем, т.е. он уже меньше сам по себе.
Увеличиваем png до размеров svg (как на сайте). И теперь наложим два файла в редакторе в соответствии с сайтом. Градиент делаем растром - изначально по тексту он был таким. А для чистоты эксперимента изменяем цвета, накладываем шум, вносим хаос в оптимизированное изображение.
Успешно получаем примерно такие же размеры файлов или даже хуже - svg с растром более 13 мб, png с градиентом около 3-х мб. Опять же разные алгоритмы сжатия и само качество изображения хуже. Средний размер jpeg такого же размера (5000х5000 пикс) будет примерно 4-5 мб.
Получаем: разработчики сами экспортировали файл из Figma, получили svg со встроенным битмэпом 4х4 тысячи пикселей весом в 10 мб и поняли что что-то пошло не так. И начали решать проблему сами, вместо того, чтобы озадачить ответственных. Или их нет и делал дизайн индус-фрилансер, который ушел в закат. А дальше начались шаманские пляски с бубном. И на каком-то этапе они изменили размеры в пикселях и убрали градиент, который давал большое увеличение веса файла, плюс оптимизация цвета. Скорее всего достаточно было на первой попытке открыть векторный файл в векторном же редакторе, увидить кривой битмап и далее по списку.
А вывод какой? Не в оптимизации сайта, а во взаимодействии между отделами. Точнее, его отсутствии.
У меня png без оптимизации (с градиентом и сеткой) получился около 0,8 мб, jpeg с фоном как на сайте 0,7 мб. Это без каких либо ухищрений. А так при желании тут все изображение можно сделать svg, кроме 5 мелких фото. Такой вот реверс-инжиниринг в дизайне.
sim31r
29.09.2021 01:38Ну можно пойти еще дальше, уже только теоретические методы.
Разработать исполняемый файл, для генерации исходного изображения. Фон кажется можно создать алгоритмически, квадратная сетка и градиент синего. Десяток строк кода.
Сжать данные нейронной сетью и передавать только веса нейронов для восстановления исходного образа. Тут чем выше допустимый уровень абстракции, тем выше сжатие.
Aquahawk
Люблю такие штуки. Как инженер. А как руководитель разработки - нет. Стоимость производства такого арта космическая. Внятно обучить этому дизайнеров, поставить на поток, чтобы стабильно получать подобный эффект по качеству нереально. Привлекать к этом разработчика смысла никакого не имеет. Лучше он что-то более полезное для бизнеса за это время сделает. Из практики по хоть сколько-то устоявшимся продуктам, которые привлекают пользователя, значимого эффекта на деньги от ускорения загрузки не замечено. Понятно что если продукт грузится минуту это жесть, и то не всегда, но начиная с определённых величин затраты на сокращение времени загрузки всё больше, а эффекта всё меньше. Что не отменяет красоты решения, а также того факта, что еще 15 лет назад во флеше так уже делали одним кликом(convert to bitmap) и более того, там нормально работал прозрачный jpeg в любой комбинации с вектором. Но уже тогда подобные рекомендации на поток нормально не ставились.
DistortNeo
Да, я бы остановился на экспериментах с WebP.
Дальнейшие улучшения уже слишком трудозатратны и не оправдывают себя.
rexen
Тут именно что нужно "технико-экономическое обоснование". Одно дело - акционный лэндинг для местного сельпо, другое дело - какой-нибудь Алиэкспресс с миллионами закачек. В первом случае на художественных "приседаниях" можно и нужно экономить, т.е. не заморачиваться. Во втором - воевать за каждый байт. На практике каждый проект оптимизируется где-то на удобной конкретно ему середине.
PS: хотя на фоне этих экономий считанных килобайтов иногда просто до слёз обидно видеть в статьях даже на Хабре иллюстрации в статье весом под десяток МегаБайт - люди (технари!) прямо со своих многомегапиксельных айфонов вываливают фотки непосредственно в статью - банально ни ресайза, ни кропа... я уж не говорю про какую-то там оптимизацию.
Aquahawk
Только али тормозит постоянно разлогинивает, что оказывает влияние на продукт гораздо большее, и даже в али приложить программистов в другие задачи гораздо эффективнее. И даже с такими глюками али продолжает развиваться, потому что предлагает уникальный товар. И при высокой замотивированности пользователя, начиная с определённого уровня качества сервиса, улучшение этого качества серсива не позволит сильно больше заработать, а очень часто это будет неизмеримо вообще.