Простые решения—ресайз картинок для вебсервиса

Я занимаюсь проектом adopt.com.ua—каталог котиков и собачек на пристройство. Основной его частью является контент—фото животных.

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

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

Как она решается обычно? Несколько вариантов:

  1. Фото ресайзится в момент загрузки, на сервере. Для этого можно использовать SDK вашей платформы или сторонние утилиты, например ImageMagick. Недостатки—лишняя нагрузка на сервер, необходимость тянуть себе зависимости, иногда бинарные. Если запросы будут частыми, то на сервере может закончиться память—для ресайза картинка обычно пережимается, я сталкивался с такой проблемой.
  2. Фото ложится в очередь и ресайзится кем-то другим. Например, с появлением serverless стало модным перекладывать это на лямбды. Картинка попадает на сервер — грузим её на s3 — триггерим лямбду — лямбда ресайзит и ложит картинку обратно и опционально триггерит сервер чтобы тот обновил базу. Такой способ неограниченно масштабируется, но содержит много движущихся частей. Это решение я применял когда работал в стартапах и для клиентских проектов.

Для адопта тоже нужно было что-то придумывать. Я собрался делать лямбду, потому что не хотелось тащить ImageMagick на хероку, а потом вспомнил об одном сервисе, про который мне рассказал CTO OneDome—ImageKit.

Суть такова—ты заливаешь картинку, а дальше просто формируешь урлы типа https://cdn.imagekit.io/picture.jpeg?w=1024&h=768 и сервис сам на лету отдает тебе изображение в нужном размере. Таким образом можно строить приложения вообще без CDN. Тогда мы планировали использовать это в одном из проектов, но до реализации дело не дошло.

ImageKit просит мелкий прайс за свои услуги, но я решил пойти по-другому, т.к. хотел хранить картинки у себя. В момент, когда пользователь загружает картинку, я тут же сгружаю её на ImageKit, потом скачиваю себе по урлу уже отресайзенную в нужном размере и ложу на свой CDN. Таким образом ImageKit у меня используется только как ресайзер, без хранилища. Если вдруг они пропадут то ничего не сломается—просто картинки будут большими, но продолжат отображаться.

Никаких лямбд не нужно, никаких бинарных зависимостей, только два http запроса—залить на ImageKit и скачать обратно. Всё это делается бэкграунд джобой.

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

А в результате ресайза картинок вес главной страницы сократился в ~10 раз.

upd: в комментах накидали еще несколько прикольных сервисов:

  1. vault8.io — умеет то же самое что ImageKit, но еще и фильтры
  2. imgproxy — то же самое, не для любителей селф-хостед

Понравился материал? Подписывайся на мой телеграм канал: https://t.me/full_of_hatred