Оптимизация изображений
ONREZA автоматически оптимизирует изображения на лету — конвертирует в современные форматы (WebP, AVIF), изменяет размеры и применяет сжатие.
Как это работает
Заголовок раздела «Как это работает»Вместо прямых ссылок на изображения используйте специальный endpoint:
/_onreza/image?url=/images/photo.jpg&w=640&q=75Платформа автоматически:
- Берёт оригинальное изображение из вашего деплоя
- Конвертирует в указанный формат (WebP/AVIF)
- Изменяет размеры согласно параметрам
- Кэширует результат в объектное хранилище для быстрой доставки
Базовое использование
Заголовок раздела «Базовое использование»Простой пример
Заголовок раздела «Простой пример»<!-- Оригинал --><img src="/images/photo.jpg" alt="Photo" />
<!-- Оптимизированная версия 640px WebP --><img src="/_onreza/image?url=/images/photo.jpg&w=640" alt="Photo" />Параметры URL
Заголовок раздела «Параметры URL»| Параметр | Описание | Пример |
|---|---|---|
url | Обязательный. Путь к изображению относительно корня | /images/photo.jpg |
w | Обязательный. Ширина в пикселях (из разрешённых) | 640 |
h | Высота в пикселях. Если не указана — пропорционально | 480 |
q | Качество сжатия (1-100). По умолчанию: 75 | 80 |
f | Формат: webp или avif. По умолчанию: auto | webp |
fit | Режим обрезки: cover, contain, fill. По умолчанию: cover | contain |
blur | Gaussian blur (0-250). Для placeholder-ов | 20 |
dpr | Device Pixel Ratio (1-5). Для Retina дисплеев | 2 |
Разрешённые ширины
Заголовок раздела «Разрешённые ширины»Используйте только следующие значения ширины:
16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840
Примеры использования
Заголовок раздела «Примеры использования»Responsive images с srcset
Заголовок раздела «Responsive images с srcset»<img src="/_onreza/image?url=/images/hero.jpg&w=640" srcset=" /_onreza/image?url=/images/hero.jpg&w=640 640w, /_onreza/image?url=/images/hero.jpg&w=1080 1080w, /_onreza/image?url=/images/hero.jpg&w=1920 1920w " sizes="(max-width: 768px) 640px, (max-width: 1200px) 1080px, 1920px" alt="Hero"/>AVIF с лучшим сжатием
Заголовок раздела «AVIF с лучшим сжатием»<picture> <source srcset="/_onreza/image?url=/images/photo.jpg&w=800&f=avif" type="image/avif" /> <source srcset="/_onreza/image?url=/images/photo.jpg&w=800&f=webp" type="image/webp" /> <img src="/_onreza/image?url=/images/photo.jpg&w=800" alt="Photo" /></picture>Thumbnail с обрезкой
Заголовок раздела «Thumbnail с обрезкой»<!-- Аватар 200×200, обрезка по центру --><img src="/_onreza/image?url=/images/avatar.jpg&w=200&h=200&fit=cover" width="200" height="200" alt="Avatar"/>Low Quality Image Placeholder (LQIP)
Заголовок раздела «Low Quality Image Placeholder (LQIP)»<img src="/_onreza/image?url=/images/hero.jpg&w=1920&q=80" style="background-image: url('/_onreza/image?url=/images/hero.jpg&w=64&blur=20&q=30'); background-size: cover;" alt="Hero"/>Retina/HiDPI изображения
Заголовок раздела «Retina/HiDPI изображения»<!-- Для дисплеев 2x фактический размер 400px, отображается как 200px --><img src="/_onreza/image?url=/images/logo.png&w=200&dpr=2" width="200" height="100" alt="Logo"/>S3 Cache
Заголовок раздела «S3 Cache»Оптимизированные изображения автоматически кэшируются в объектном хранилище для мгновенной доставки при повторных запросах.
Формат ключа кэша
Заголовок раздела «Формат ключа кэша»{image_cache_s3_prefix}/{project_id}/{short_sha}/{path_hash}/{width}x{height}_{quality}_{format}_{fit}_{blur}TTL кэша
Заголовок раздела «TTL кэша»| Тип | TTL |
|---|---|
| Оптимизированные изображения | 1 год |
| Оригиналы | Не кэшируются в объектном хранилище (берутся из деплоя) |
Безопасность
Заголовок раздела «Безопасность»SSRF Protection
Заголовок раздела «SSRF Protection»Image Optimization service защищён от SSRF (Server-Side Request Forgery) атак:
- Только relative URL: Параметр
urlдолжен начинаться с/ - Path Traversal Protection: Запрещены последовательности
..,%2e,%252e - URL Whitelist: Ограничен доступ только к изображениям из вашего деплоя
Проверка путей
Заголовок раздела «Проверка путей»// Запрещённые пути (вернут 400 Bad Request)/_onreza/image?url=https://evil.com/image.jpg // Абсолютный URL/_onreza/image?url=//evil.com/image.jpg // Protocol-relative URL/_onreza/image?url=/../../etc/passwd // Path traversal/_onreza/image?url=/..%2f..%2fsecret.txt // URL-encoded traversalRuntime SDK
Заголовок раздела «Runtime SDK»Для программной генерации URL в серверном коде используйте @onreza/runtime/image:
npm install @onreza/runtime# или: pnpm add / yarn add / bun addimport { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
// Базовый URLconst url = imageUrl('/images/hero.jpg', { width: 1080 });// → '/_onreza/image?url=%2Fimages%2Fhero.jpg&w=1080&q=75'
// С параметрамиconst optimized = imageUrl('/images/photo.jpg', { width: 640, quality: 80, format: 'webp', fit: 'cover', dpr: 2,});
// Responsive srcsetconst srcset = generateSrcset('/images/photo.jpg', [640, 1080, 1920], { quality: 80 });// → '/_onreza/image?...&w=640 640w, /_onreza/image?...&w=1080 1080w, ...'Responsive component (пример)
Заголовок раздела «Responsive component (пример)»import { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
function responsiveImage(src: string, alt: string, sizes = '100vw') { const widths = [640, 1080, 1920]; return `<img src="${imageUrl(src, { width: 1080 })}" srcset="${generateSrcset(src, widths)}" sizes="${sizes}" alt="${alt}" loading="lazy" decoding="async" />`;}→ Полный API reference: Runtime SDK
Интеграция с фреймворками
Заголовок раздела «Интеграция с фреймворками»Next.js
Заголовок раздела «Next.js»Создайте кастомный loader:
export default function onrezaLoader({ src, width, quality }: { src: string; width: number; quality?: number;}) { const params = new URLSearchParams(); params.set('url', src); params.set('w', width.toString()); params.set('q', (quality || 75).toString()); return `/_onreza/image?${params.toString()}`;}
// next.config.jsmodule.exports = { images: { loader: 'custom', loaderFile: './onreza-image-loader.ts', },};Используйте стандартный <Image> компонент:
import Image from 'next/image';
<Image src="/images/photo.jpg" width={800} height={600} alt="Photo"/>Используйте <Image> компонент с кастомным endpoint:
---import { Image } from 'astro:assets';---
<Image src="/images/photo.jpg" width={640} height={480} alt="Photo" inferSize/>Или напрямую:
<img src="/_onreza/image?url=/images/photo.jpg&w=640" alt="Photo" width="640" height="480"/>Ограничения
Заголовок раздела «Ограничения»| Параметр | Лимит |
|---|---|
| Максимальный размер оригинала | 20 MB |
| Разрешённые ширины | 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840 |
| Максимальный DPR | 5 |
| Максимальный blur | 250 |
| Входные форматы | JPEG, PNG, GIF, WebP |
| Выходные форматы | WebP, AVIF |
Troubleshooting
Заголовок раздела «Troubleshooting»”Width not in allowed sizes”
Заголовок раздела «”Width not in allowed sizes”»Используйте только разрешённые ширины: 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840
”Source image exceeds max size”
Заголовок раздела «”Source image exceeds max size”»Оригинальное изображение больше 20 MB. Оптимизируйте оригинал перед загрузкой.
”url must be a relative path”
Заголовок раздела «”url must be a relative path”»Параметр url должен быть относительным путём (начинаться с /), не полным URL.
”Path traversal detected”
Заголовок раздела «”Path traversal detected”»Обнаружена попытка path traversal. Убедитесь, что путь не содержит .. или подобных последовательностей.
Советы по производительности
Заголовок раздела «Советы по производительности»- Используйте srcset — позвольте браузеру выбрать оптимальный размер
- Приоритет AVIF — лучшее сжатие, но проверяйте поддержку браузерами
- Lazy loading — добавляйте
loading="lazy"для изображений ниже fold - Размеры — всегда указывайте
widthиheightдля предотвращения layout shift - DPR — используйте
dpr=2для Retina дисплеев, но не злоупотребляйте высокими значениями
См. также
Заголовок раздела «См. также»- Runtime SDK — полный API reference (
imageUrl,generateSrcset) - Edge Runtime — API доступные в изоляте
- D1 Database — для хранения метаданных изображений
- Кастомные домены — для красивых URL изображений