Генерация миниатюр изображений на сервере: WebP, AVIF, очереди

Генерация миниатюр изображений: решаем проблему LCP и веса страниц

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Генерация миниатюр изображений на сервере: WebP, AVIF, очереди
Средний
~2-3 дня

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    982
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    995

Генерация миниатюр изображений: решаем проблему LCP и веса страниц

Сайт с большим количеством изображений тормозит? Каждая страница грузит оригиналы 4000x3000 пикселей — LCP зашкаливает, пользователи уходят. Наш опыт показывает, что автоматическая генерация миниатюр на сервере — единственный способ удержать Core Web Vitals в норме без ручной обработки каждого файла. Мы реализуем решение за 2–3 дня под ключ: настройка очередей, форматы WebP/AVIF, кэширование на CDN. Это снижает объем передаваемых данных на 40–60% и улучшает LCP на 30–50%, что напрямую влияет на конверсию.

Как работает генерация миниатюр в очереди?

Асинхронная генерация — стандарт для современных проектов с высокой нагрузкой на загрузку. После того как пользователь загрузил оригинал в S3 или локальное хранилище, в очередь (Laravel Job, BullMQ, или AWS SQS) отправляется задача. Она создаёт несколько размеров: thumb (200x200) для списков, medium (600x400) для карточек, large (1200x800) для галерей. Пользователь не ждёт — ответ приходит сразу, а миниатюры появляются через секунды. При этом очередь не блокирует веб-сервер: обработка происходит в фоновом процессе.

Почему стоит выбрать WebP/AVIF?

Современные форматы сжатия со потерями дают 25–50% экономии размера без заметного падения качества. Для браузеров, не поддерживающих AVIF, автоматически отдаётся WebP через элемент <picture>. Это снижает LCP на 30–50%. AVIF (на основе AV1) обеспечивает наилучшее сжатие, но требует больше ресурсов CPU для кодирования. WebP — универсальный выбор, поддерживаемый 96% браузеров.

Как выбрать стратегию генерации: очередь vs ленивая генерация?

Для сайтов с высокой частотой загрузок (фотогалереи, маркетплейсы) асинхронная очередь — единственный вариант: она не блокирует ответ и позволяет масштабировать обработку горизонтально. Ленивая генерация через Glide подходит для проектов с редкими загрузками или когда размеры миниатюр заранее неизвестны. Она генерирует изображение по первому запросу и кэширует его. Однако при первом обращении пользователь ждёт генерации. Мы помогаем выбрать стратегию на основе ваших метрик: количество загрузок в день, средний размер изображений, бюджет на инфраструктуру.

Что входит в нашу работу

  • Аудит текущей системы хранения и обработки изображений
  • Выбор стратегии: очередь или ленивая генерация
  • Реализация генерации миниатюр с нужными размерами и форматами
  • Настройка кэширования (CDN, Cache-Control)
  • Интеграция с существующим API и хранилищем (S3, облачный сервер)
  • Документация по использованию и поддержке

Почему Sharp справляется быстрее конкурентов?

Библиотека Sharp (на базе libvips) выполняет операции в 4–5 раз быстрее, чем ImageMagick или GD для типовых задач. Это достигается за счёт работы с изображением в оперативной памяти без промежуточных файлов и эффективного использования кэша процессора. Для Node.js-проектов Sharp — стандарт де-факто. Для PHP-проектов рекомендуем Intervention Image с очередями или Glide для ленивой генерации.

Форматы и оптимизация: сравнение

Формат Размер относительно JPEG Совместимость Рекомендуемое качество
JPEG 100% (база) Все браузеры 85%
WebP 70–80% 96%+ 80%
AVIF 40–60% 90%+ 60%
// Выбор формата по поддержке браузером const output = sharp(buffer) .resize(800) .toFormat(supportsAvif ? 'avif' : supportsWebp ? 'webp' : 'jpeg', { quality: supportsAvif ? 60 : supportsWebp ? 80 : 85, }); 

AVIF даёт до 50% экономии относительно JPEG при том же качестве. WebP поддерживается всеми современными браузерами. Для максимальной совместимости используйте <picture> с несколькими форматами.

Laravel: Intervention Image + очередь

// Модель с автоматической генерацией миниатюр class Image extends Model { const SIZES = [ 'thumb' => [200, 200], 'medium' => [600, 400], 'large' => [1200, 800], ]; } // Job для асинхронной генерации class GenerateImageThumbnails implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable; public function __construct(private Image $image) {} public function handle(): void { $originalPath = Storage::disk('s3')->path($this->image->path); $img = \Intervention\Image\Facades\Image::make($originalPath); foreach (Image::SIZES as $size => [$width, $height]) { $resized = clone $img; $resized->fit($width, $height); // crop по центру $thumbPath = str_replace('original/', "{$size}/", $this->image->path); Storage::disk('s3')->put($thumbPath, $resized->encode('webp', 85)->__toString()); } $this->image->update(['processed' => true]); } } // Контроллер загрузки public function store(Request $request): JsonResponse { $path = Storage::disk('s3')->putFile('original', $request->file('image')); $image = Image::create([ 'path' => $path, 'user_id' => auth()->id(), 'processed' => false, ]); GenerateImageThumbnails::dispatch($image); return response()->json(['id' => $image->id]); } 

Node.js: Sharp

Sharp — самая быстрая Node.js-библиотека для обработки изображений (на базе libvips).

import sharp from 'sharp'; import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3'; const SIZES = { thumb: { width: 200, height: 200 }, medium: { width: 600, height: 400 }, large: { width: 1200, height: 800 }, } as const; async function generateThumbnails(s3Key: string): Promise<Record<string, string>> { const s3 = new S3Client({ region: 'eu-west-1' }); // Скачать оригинал const { Body } = await s3.send(new GetObjectCommand({ Bucket: process.env.S3_BUCKET!, Key: s3Key, })); const buffer = Buffer.from(await (Body as any).transformToByteArray()); const results: Record<string, string> = {}; await Promise.all( Object.entries(SIZES).map(async ([name, { width, height }]) => { const thumbnail = await sharp(buffer) .resize(width, height, { fit: 'cover', position: 'centre' }) .webp({ quality: 85 }) .toBuffer(); const thumbKey = s3Key.replace('original/', `${name}/`).replace(/\.[^.]+$/, '.webp'); await s3.send(new PutObjectCommand({ Bucket: process.env.S3_BUCKET!, Key: thumbKey, Body: thumbnail, ContentType: 'image/webp', CacheControl: 'public, max-age=31536000', })); results[name] = thumbKey; }) ); return results; } 

Ленивая генерация через Glide (PHP)

Glide генерирует миниатюры по запросу с подписанным URL:

// Маршрут для изображений Route::get('/img/{path}', function (Request $request, string $path) { $server = League\Glide\ServerFactory::create([ 'source' => Storage::disk('s3')->getDriver(), 'cache' => Storage::disk('local')->getDriver(), 'cache_path_prefix' => '.cache', 'base_url' => '/img', 'max_image_size' => 2000 * 2000, ]); // Проверка подписи URL League\Glide\Signatures\SignatureFactory::create(config('app.key')) ->validateRequest('/img/' . $path, $request->all()); return $server->getImageResponse($path, $request->all()); })->where('path', '.*'); // Генерация подписанного URL $url = (new League\Glide\Urls\UrlBuilderFactory) ->create('/img', config('app.key')) ->getUrl('uploads/photo.jpg', ['w' => 400, 'h' => 300, 'fit' => 'crop']); 

Срок реализации и стоимость

Генерация миниатюр в очереди (Laravel Job или BullMQ Worker) с сохранением в S3: 2–3 дня. С lazy generation через Glide и CDN-кэшированием: 3–4 дня. Сложные проекты с интеграцией нескольких CMS — до 5 дней. Стоимость рассчитывается индивидуально в зависимости от сложности и стека. Свяжитесь с нами, чтобы получить консультацию и точные сроки. Закажите аудит и оптимизацию изображений — мы подберем оптимальную стратегию для вашего проекта.

Наши инженеры имеют 5+ лет опыта в оптимизации высоконагруженных сайтов. Уже более 30 проектов с подобной архитектурой успешно работают в продакшене. Получите консультацию — мы оценим ваш проект и предложим решение под ключ, гарантируя снижение LCP на 30–50% после внедрения.