Перейти к содержимому

Оптимизация изображений

ONREZA автоматически оптимизирует изображения на лету — конвертирует в современные форматы (WebP, AVIF), изменяет размеры и применяет сжатие.

Вместо прямых ссылок на изображения используйте специальный endpoint:

/_onreza/image?url=/images/photo.jpg&w=640&q=75

Платформа автоматически:

  1. Берёт оригинальное изображение из вашего деплоя
  2. Конвертирует в указанный формат (WebP/AVIF)
  3. Изменяет размеры согласно параметрам
  4. Кэширует результат в объектное хранилище для быстрой доставки
<!-- Оригинал -->
<img src="/images/photo.jpg" alt="Photo" />
<!-- Оптимизированная версия 640px WebP -->
<img src="/_onreza/image?url=/images/photo.jpg&w=640" alt="Photo" />
ПараметрОписаниеПример
urlОбязательный. Путь к изображению относительно корня/images/photo.jpg
wОбязательный. Ширина в пикселях (из разрешённых)640
hВысота в пикселях. Если не указана — пропорционально480
qКачество сжатия (1-100). По умолчанию: 7580
fФормат: webp или avif. По умолчанию: autowebp
fitРежим обрезки: cover, contain, fill. По умолчанию: covercontain
blurGaussian blur (0-250). Для placeholder-ов20
dprDevice Pixel Ratio (1-5). Для Retina дисплеев2

Используйте только следующие значения ширины: 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840

<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"
/>
<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>
<!-- Аватар 200×200, обрезка по центру -->
<img
src="/_onreza/image?url=/images/avatar.jpg&w=200&h=200&fit=cover"
width="200"
height="200"
alt="Avatar"
/>
<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"
/>
<!-- Для дисплеев 2x фактический размер 400px, отображается как 200px -->
<img
src="/_onreza/image?url=/images/logo.png&w=200&dpr=2"
width="200"
height="100"
alt="Logo"
/>

Оптимизированные изображения автоматически кэшируются в объектном хранилище для мгновенной доставки при повторных запросах.

{image_cache_s3_prefix}/{project_id}/{short_sha}/{path_hash}/{width}x{height}_{quality}_{format}_{fit}_{blur}
ТипTTL
Оптимизированные изображения1 год
ОригиналыНе кэшируются в объектном хранилище (берутся из деплоя)

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 traversal

Для программной генерации URL в серверном коде используйте @onreza/runtime/image:

Окно терминала
npm install @onreza/runtime
# или: pnpm add / yarn add / bun add
import { imageUrl, generateSrcset, DEFAULT_SIZES } from '@onreza/runtime/image';
// Базовый URL
const 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 srcset
const srcset = generateSrcset('/images/photo.jpg', [640, 1080, 1920], { quality: 80 });
// → '/_onreza/image?...&w=640 640w, /_onreza/image?...&w=1080 1080w, ...'
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

Создайте кастомный loader:

onreza-image-loader.ts
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.js
module.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
Максимальный DPR5
Максимальный blur250
Входные форматыJPEG, PNG, GIF, WebP
Выходные форматыWebP, AVIF

Используйте только разрешённые ширины: 16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840

Оригинальное изображение больше 20 MB. Оптимизируйте оригинал перед загрузкой.

Параметр url должен быть относительным путём (начинаться с /), не полным URL.

Обнаружена попытка path traversal. Убедитесь, что путь не содержит .. или подобных последовательностей.

  1. Используйте srcset — позвольте браузеру выбрать оптимальный размер
  2. Приоритет AVIF — лучшее сжатие, но проверяйте поддержку браузерами
  3. Lazy loading — добавляйте loading="lazy" для изображений ниже fold
  4. Размеры — всегда указывайте width и height для предотвращения layout shift
  5. DPR — используйте dpr=2 для Retina дисплеев, но не злоупотребляйте высокими значениями