Ответ
Да, Nginx может генерировать изображения на лету с помощью официального модуля ngx_http_image_filter_module. Однако это не всегда оптимальный подход для продакшена из-за нагрузки на CPU.
Базовый пример ресайза:
location ~* ^/images/resized/(d+)x(d+)/(.+.(jpg|jpeg|png))$ {
# $1 - ширина, $2 - высота, $3 - имя файла
image_filter resize $1 $2;
image_filter_buffer 10M; # Максимальный размер исходного изображения
image_filter_jpeg_quality 85; # Качество для JPEG
root /path/to/original/images;
try_files /$3 =404; # Ищем оригинальный файл
}
Запрос к /images/resized/200x100/product.jpg вернет уменьшенную копию.
Критически важные методы оптимизации:
-
Кеширование — главный инструмент. Кешируйте сгенерированные миниатюры на диске или в памяти.
proxy_cache_path /var/cache/nginx/images levels=1:2 keys_zone=img_cache:10m inactive=30d; location ~* ^/images/resized/ { image_filter resize $arg_w $arg_h; proxy_cache img_cache; proxy_cache_key "$uri$is_args$args"; proxy_cache_valid 200 30d; add_header X-Cache-Status $upstream_cache_status; # ... остальная конфигурация image_filter } -
Предварительная (offline) генерация — для фиксированного набора размеров (превью, карточка товара) генерируйте изображения один раз на этапе загрузки товара, используя библиотеки типа ImageMagick или Pillow. Nginx тогда просто отдает статику.
-
Использование CDN — разместите сгенерированные или оригинальные изображения в CDN (CloudFront, Cloudflare). Многие CDN имеют встроенные функции ресайза "на лету" (например, Cloudflare Images, Imgix), что снимает нагрузку с вашего сервера.
-
Оптимизация форматов — настройте отдачу современных форматов (WebP, AVIF) для поддерживающих их браузеров, используя директиву
mapдля проверки заголовкаAccept. -
Отказ от Nginx Image Filter в пользу специализированного сервиса — для высоких нагрузок лучше вынести обработку изображений в отдельный микросервис (на Go, Python с Pillow) или использовать облачные сервисы. Nginx в этой схеме выступает как прокси или отдает уже готовые файлы из кеша.