Комментарии 28
Спасибо! Дай бог мне добраться до применения этого в боевом окружении.
Или я прочитал криво, или вы изобрели велосипед. Чем не устроило решение на Nginx?
https://nginx.org/ru/docs/http/ngx_http_image_filter_module.html
https://zaiste.net/network/nginx/howtos/howto-resize-on-the-fly-cache-images-nginx/
Я с целью понять разницу, а не докопаться.
Он умеет внешние изображения ресайзить, а nginx вроде как только те, что лежат на сервере
Есть еще вот такой модуль https://nginx-extras.getpagespeed.com/modules/small-light/ Мы написали небольшой кофижек в 30 строк для realtime конвертации в webp, уже почти год в продакшене - полет нормальный (с кешом, разумеется)
К своему стыду даже не знал что у nginx такая есть. Но наш вариант получился скорее по накатанной, был процесс оптимизаций на этапе сборки, он стал занимать много времени. Был налаженный процесс разработки фронтовых микросервисов. Мы решили объединить и получился такой результат =). К тому же наш микросервис поддерживает avif и можно пополнять необходимой логикой под наши потребности. Так же ждем выхода webp2 что бы сразу заюзать.
Завел таску в техдолг на замену на лендосах родного некстовского. В нексте сильно раздражает необходимость часто заранее знать размер, что не всегда возможно + присутствует видимый лаг между рендером страницы и появлением изображения.
Если не секрет, а чем именно вас не устроило готовое решение в виде imgproxy?
Спасибо за ссылку, судя по спонсорству злых марсиан достойная альтернатива
Если честно гугл мне его не показывал. Спасибо за наводку, изучим. Если удовлетворит нашим потребностям перенаправим клиентский компонент на него.
Если будет возможность, поделитесь потом мнением, очень интересно.
Выводы следующие:
imgproxy конвертирует в формат webp и avif в 2 раза дольше чем наш микросервис. Кроме того потребляется в 2 на webp и 4 на avif больше раз процессорных ресурсов. По оперативной памяти работают одинаково.
Не удалось найти опции для прохождения базовых авторизаций в закрытых контурах. А так же ограничений на источники данных, что бы предотвратить использование запущенного микросервиса для конвертации чужих картинок.
Как результат - imgproxy не удовлетворяет нашим потребностям.
Я аж профиль на Хабре воскресил после такого заявления :)
Можно спросить, как вы тестировали? В AVIF я еще могу поверить (libaom обогнал rav1e по скорости, а мы затянули с переездом), но в WebP - никак. После пересборки libheif с libaom вместо rav1e результаты такие: https://gist.github.com/DarthSim/eecae5e43352f4d552f1088f4d9a4b34
Любопытно взглянуть на ваш тестовый сетап :)> Не удалось найти опции для прохождения базовых авторизаций в закрытых контурах
Такого запроса не поступало, поэтому и фичи такой нет. Но все решается через issue или даже pull request ;)
> А так же ограничений на источники данных
IMGPROXY_ALLOWED_SOURCES
(просто мимо проходил)
Может, для теста какую-то более репрезентативную картинку использовать? Интересны тесты отдельно для HDReady, FullHD, 4K и картинки с большим количеством элементов и просто десятком градиентов.
Тест делал на личном хостинге в selectel с минимальной vds.
Развернул там два контейнера.
Картинку брал из соседнего контейнера. https://labeg.ru/content/images/portfolio/avilex/ncuo_10-1920w.jpg и ресайзил до 500 пикселей по ширине.
Сетап был крайне простой, открывал картинку в браузере несколько раз без кеша и в нетворке замерял среднее время =)
В итоге:
ImageOpitimize - webp : 152ms
ImxProxy - webp : 258ms
ImageOpitimize - avif : 2.53s
ImxProxy - avif : падало с кодом 503 и сообщением Timeout, но сейчас смотрю починили и теперь 2.57s
Для чистоты эксперимента в вашем тесте стоит указать ресайз отличный от исходного размера картинки =)
Ресурсоемкость замерял не совсем научным путем, но показательным.
Фиолетовая рисочка ImgProxy, синяя ImageOptimize. В новой версии эта проблема так же решена =).До пул реквестов ближайшее время, к сожалению, руки не дойдут. Микросервис у вас действительно интересный и возможно как ни будь попозже мы переключимся на него =)
Ну вы что, тестирование браузером - это как-то обидно даже :) Но я все равно вам должен: пока делал бенчмарки, увидел регрессию в последних образах из-за ошибки в CFLAGS при сборке зависимостей :)
Для чистоты эксперимента в вашем тесте стоит указать ресайз отличный от исходного размера картинки =)
Раз был заявлен более быстрый энкодинг, то я тестировал исключительно его, специально выключая ресайз. Вот бенчмарки с ресайзом вашей картинки (после устранения регрессии): https://gist.github.com/DarthSim/f3d78285b4dcc84ab22a5ae7ff18ffb5.
Энкодинг в AVIF очень тяжелый, поэтому он съедает все время, и различия минимальны. Хотя, если выкрутить IMGPROXY_AVIF_SPEED
, то она выдает около 5 RPS. Держу пари, Sharp тоже умеет устанавливать speed/effort, так что, попробуйте.
WebP очевидно легче, поэтому там разница заметнее. Не уверен, где именно imgproxy взяла свой отрыв, но сдается мне, что дело в моделях конкурентности, потому что в браузере разница незаметна.
Насчёт первого пункта ничего не скажу (странно, особенно касаемо различий в разы, ну да ладно), но что касается "что бы предотвратить использование запущенного микросервиса для конвертации чужих картинок", то там ведь сигнатуру надо формировать для урлов - тогда и чужие картинки подсовывать не получится, потому что если урл поменять, то сигнатура будет невалидной. Вот тут - подробнее.
Золотое правило - надо написать велосипед, чтобы люди подсказали альтернативы
Спасибо, интересная было прочесть
Я одно время статику относящуюся к дизайну на сайте оптимизировал и осознал что малоцветные картинки в PNG могут быть сильно меньше других форматов, если у них палитра 2-3 цвета.
Но с полноцветными джипегами типа картинок товаров такое не пройдет, на досуге попробую поиграться вашим решением.
>Если же сайт загрузился быстро – клиент приступит к его изучению исключительно с положительными эмоциями.
Люди вряд ли заходят на сайт МТС с положительными эмоциями.
>Но по факту у нас на этот микросервис стоит ограничение в 4 ядра, и картинки в среднем в 4 раза меньше, из-за чего конвертируется в 8 раз быстрее.
4*4 == 8?
Почему вместо picture и source используется ручная проверка на JavaScript?
Изначально была проверка для нескольких компонентов, в т.ч. для использования в css. И в этом компонента она сохранилась как есть.
Насчет поменять ли на picture что бы решал сам браузер - не уверен что в этом есть смысл. В доме будет больше не нужных элементов и по стилям оно не всегда обратно совместимо с img.
Есть нюанс, если контейнер станет шире ширины картинки, то она будет ресайзиться в сторону увеличения и сильно проседать в качестве, покурил доку и придумал вот такое решение:
let img = await sharp(data)
.metadata()
.then(({ width: originalWidth }) => sharp(data)
.resize({ width: Math.min(originalWidth, intSize) }));
Как мы уменьшаем размер изображений на веб-страницах в 10 раз с помощью нашего оптимизатора