SW Shopware 6 Intermedio

DataFirefly Image Optimizer — Documentación Shopware 6

Instalación, configuración WebP/AVIF, integración CDN, API Twig y resolución de problemas del plugin Image Optimizer para Shopware 6.6 y 6.7.

Actualizado Versión del módulo 1.0.0

DataFirefly Image Optimizer transforma automáticamente cada imagen de medios Shopware en variantes WebP y AVIF, recomprime los JPEG y PNG originales, y reescribe las URL hacia su CDN — sin modificar el tema. Esta documentación cubre la instalación, la configuración completa, la API Twig expuesta a los temas, y la resolución de problemas.

Instalación

El plugin se entrega como ZIP. Dos métodos de instalación, funcionalmente equivalentes.

Vía la administración Shopware

  1. Ajustes → Sistema → Extensiones → Subir extensión
  2. Seleccione DfImageOptimizer-1.0.0.zip
  3. Haga clic en Instalar y luego Activar
  4. Limpiar caché: Ajustes → Sistema → Caché e Índices → Limpiar

Vía CLI (recomendado)

cd /ruta/a/shopware
unzip DfImageOptimizer-1.0.0.zip -d custom/plugins/

sudo -u www-data setsid php bin/console plugin:refresh
sudo -u www-data setsid php bin/console plugin:install --activate DfImageOptimizer
sudo -u www-data setsid php bin/console cache:clear
sudo -u www-data setsid php bin/console theme:compile
Consejo. theme:compile es obligatorio tras la instalación para que el override Twig del componente thumbnail esté activo en el storefront. Sin esta etapa, las etiquetas <picture> no se generarán aunque WebP y AVIF se produzcan.

Verificación post-instalación

Vaya al menú admin Catálogos → Image Optimizer. El panel debe mostrarse con una tarjeta Capacidades del servidor indicando en tiempo real:

  • Versión PHP detectada (8.2 mínimo)
  • Presencia de Imagick (recomendado)
  • Presencia de GD (obligatorio)
  • Soporte efectivo WebP — debe ser ✓
  • Soporte efectivo AVIF — puede ser ✗ según el servidor, no bloqueante
  • Motor recomendado: Imagick o GD

Arquitectura en dos palabras

Cuando se sube una imagen, el plugin escucha el evento entity media.written, carga la imagen en un archivo temporal local, y luego produce en paralelo:

  • El original recomprimido (reemplaza el archivo si Comprimir original está marcado)
  • Un hermano WebP al lado con extensión acumulada: foo.jpgfoo.jpg.webp
  • Un hermano AVIF al lado: foo.jpgfoo.jpg.avif

Las miniaturas Shopware generadas por el ThumbnailService nativo se procesan de la misma manera. En el storefront, el override Twig de storefront/component/image/thumbnail.html.twig envuelve la etiqueta <img> en un <picture> con fuentes AVIF, WebP y fallback original — el navegador elige automáticamente el formato más ligero que soporta.

Configuración

Acceso: Ajustes → Sistema → Extensiones → DfImageOptimizer → Configurar. Siete tarjetas agrupan las opciones.

Tarjeta «General»

Opción Defecto Efecto
Auto-optimizar al subir Activado Activa el pipeline inmediatamente en cada subida. Desactive si prefiere procesar todo en segundo plano vía cron.
Procesar miniaturas Activado Genera WebP/AVIF también para las miniaturas Shopware (típicamente 4-6 tamaños por imagen origen).

Tarjeta «WebP»

Opción Defecto Recomendación
Activar WebP Activado Mantener activado salvo caso muy específico. WebP es compatible con el 96% de navegadores.
Calidad WebP (1-100) 82 75-85 para buen equilibrio. 90+ para fotografía de alta gama, 70 para catálogo voluminoso.
Lossless para PNG Desactivado Active solo si sus PNG contienen texto o gráficos nítidos (logos, iconos). Si no, el modo lossy da mejores ganancias.

Tarjeta «AVIF»

Opción Defecto Recomendación
Activar AVIF Desactivado Active si el panel indica que su servidor soporta AVIF. Ganancia típica del 50% vs JPEG, pero codificación más lenta que WebP.
Calidad AVIF (1-100) 55 45-65 para excelente renderizado. AVIF tolera calidades más bajas que JPEG/WebP gracias a su códec moderno.
Anchura máxima para AVIF (px) 2400 Salvaguarda CPU. Imágenes mayores se omiten para AVIF pero conservan su WebP. Aumente si tiene un servidor potente.
Sobre AVIF. La codificación AVIF requiere PHP 8.1+ con el flag IMG_AVIF compilado, o Imagick con libheif. El panel Capacidades del servidor indica exactamente qué está disponible. Si AVIF no es compatible, la opción queda inoperante aunque esté marcada — sin error, simplemente no hay generación AVIF.

Tarjeta «Compresión»

Opción Defecto Recomendación
Comprimir JPG/PNG originales Activado Reemplaza el original por su versión recomprimida. Acción irreversible — desactive si quiere conservar las fuentes brutas.
Calidad JPEG (1-100) 85 85 es el estándar foto web. Bajar a 80 para ganancia adicional si la calidad sigue aceptable.
Nivel compresión PNG (0-9) 7 9 = compresión máxima pero 3-4× más lenta. 7 es el equilibrio estándar.
Eliminar metadatos EXIF/ICC Activado Ganancia típica 5 a 30 KB por foto de cámara. Conserve si gestiona contenido con perfiles cromáticos.

Tarjeta «CDN»

Opción Defecto Explicación
Activar reescritura CDN Desactivado Si desactivado, las URL apuntan a su origen. Active tras configurar su CDN.
URL base del CDN Formato: https://cdn.ejemplo.com sin slash final.
Alcance de reescritura Solo medios Vea detalle abajo.
Conservar query strings Activado Preserva parámetros cache-busting (?v=1234) en la reescritura.

Los tres alcances en detalle:

  • Solo medios — reescribe únicamente URLs comenzando por /media/. Es el más seguro y cubre el 95% de los casos de uso típicos.
  • Medios + miniaturas — añade /thumbnail/. Útil si su storefront sirve muchas miniaturas generadas dinámicamente.
  • Todos los recursos estáticos — añade /theme/, /bundles/ y /assets/. Solo elija esta opción si su CDN está bien configurado.

Tarjeta «Renderizado frontend»

Opción Defecto Efecto
Salida como <picture> Activado Envuelve los <img> del storefront en un <picture> con fuentes AVIF/WebP.
Añadir loading="lazy" Activado Lazy-loading nativo navegador. Mantener salvo solución propia.
Añadir decoding="async" Activado Permite al navegador decodificar en paralelo del parsing HTML.
Forzar width/height Activado Anti-CLS (Cumulative Layout Shift). El navegador reserva el espacio.

Tarjeta «Procesamiento por lotes»

Opción Defecto Recomendación
Tamaño de lote para tarea cron 50 50 es buen equilibrio. Suba a 100-200 si necesita recuperar un gran catálogo rápidamente.
Intervalo cron (minutos) 15 Información solo — el intervalo real lo define OptimizeImagesTask::getDefaultInterval().

Configurar un CDN — ejemplos concretos

BunnyCDN (recomendado)

  1. Cree una Pull Zone en bunny.net con su URL de origen, por ejemplo https://shop.ejemplo.com
  2. BunnyCDN le da un hostname del tipo shop-cdn.b-cdn.net
  3. En la config del plugin, ponga: https://shop-cdn.b-cdn.net
  4. Elija el alcance Solo medios para empezar
  5. Active la reescritura CDN

El plugin inyecta automáticamente <link rel="dns-prefetch" href="..."> y <link rel="preconnect" href="..." crossorigin> en el <head> del storefront — ahorro de 50 a 200 ms en la primera petición CDN.

Cloudflare

Cloudflare en modo proxy DNS estándar no necesita reescritura CDN — Cloudflare cachea automáticamente en su hostname principal. Pero si usa un Custom Hostname Cloudflare dedicado para assets (por ejemplo cdn.ejemplo.com), configúrelo aquí. Active también Cache Reserve o Polish de Cloudflare.

KeyCDN

Configuración idéntica a BunnyCDN: cree una Pull Zone, recupere la URL del tipo shop-12345.kxcdn.com, configúrela en el plugin con el prefijo https://.

AWS CloudFront

Cree una distribución CloudFront con su servidor Shopware como origen. La URL de distribución es del tipo https://d1234abc.cloudfront.net. Configure el TTL mínimo a 1 día.

Pipeline de optimización detallado

Para cada imagen a procesar, el plugin ejecuta estos pasos en orden:

  1. Descarga de la imagen origen desde el filesystem público Shopware a archivo temporal local (/tmp/dfimgopt_xxx.jpg)
  2. Si Comprimir original activado: recompresión in-place con calidad configurada, eliminación metadatos si activada.
  3. Si WebP activado: conversión a WebP, escritura del hermano foo.jpg.webp
  4. Si AVIF activado y anchura ≤ anchura máxima: conversión a AVIF, escritura del hermano foo.jpg.avif
  5. Registro en tabla df_image_optimizer
  6. Limpieza del archivo temporal vía bloque finally

Imagick se usa por prioridad cuando está disponible. GD toma el relevo si no — soporta WebP desde hace tiempo y AVIF desde PHP 8.1.

Compresión JPEG original — irreversible. Cuando la opción Comprimir original está marcada, la versión comprimida reemplaza la original en el filesystem. Si necesita las fuentes brutas para otros usos, desactive esta opción.

Tarea programada — recuperación de imágenes existentes

Activar el plugin en una tienda con ya miles de imágenes no dispara la optimización retroactiva. La tarea programada df_image_optimizer.optimize_pending se ejecuta cada 15 minutos por defecto:

  1. Consulta SQL vía LEFT JOIN sobre df_image_optimizer para identificar medios no optimizados
  2. Procesa un lote de 50 imágenes (configurable)
  3. Termina y libera el worker

En una tienda con 10.000 imágenes, cuente unas 50 horas para recuperación total. Para acelerar:

  • Aumente el tamaño de lote (pruebe 100 o 200)
  • Use el botón Ejecutar lote del panel varias veces
  • Ejecute la tarea en bucle vía CLI:
    for i in {1..100}; do sudo -u www-data setsid php bin/console scheduled-task:run-single df_image_optimizer.optimize_pending; done

API Twig expuesta a los temas

Dos helpers Twig registrados, usables en cualquier template de tema o plugin.

Filtro |df_cdn

Reescribe una URL hacia el CDN si activado, sino retorna la URL sin cambios.

<img src="{{ media.url|df_cdn }}" alt="...">
<link rel="preload" as="image" href="{{ heroImage.url|df_cdn }}">
<style>
    .hero { background-image: url("{{ bgImage.url|df_cdn }}"); }
</style>

Función df_picture()

Renderiza una etiqueta <picture> completa con fuentes AVIF, WebP y fallback original.

{{ df_picture(
    media,
    alt='Descripción accesible',
    classes='product-image card-img',
    sizes='(max-width: 768px) 100vw, 50vw'
) }}

Genera:

<picture>
    <source type="image/avif"
            srcset="https://cdn.ejemplo.com/media/foo.jpg.avif"
            sizes="(max-width: 768px) 100vw, 50vw">
    <source type="image/webp"
            srcset="https://cdn.ejemplo.com/media/foo.jpg.webp"
            sizes="(max-width: 768px) 100vw, 50vw">
    <img src="https://cdn.ejemplo.com/media/foo.jpg"
         alt="Descripción accesible"
         class="product-image card-img"
         sizes="(max-width: 768px) 100vw, 50vw"
         loading="lazy"
         decoding="async"
         width="1200"
         height="800">
</picture>

Endpoints API admin

Método Ruta Descripción
GET /api/_action/df-image-optimizer/stats Vista general + actividad 30d + capacidades servidor
POST /api/_action/df-image-optimizer/run-batch Lanza un lote. Parámetro POST opcional batchSize
GET /api/_action/df-image-optimizer/capabilities Detección servidor

Ejemplo curl:

TOKEN=$(curl -s -X POST https://shop.ejemplo.com/api/oauth/token 
    -H "Content-Type: application/json" 
    -d '{"grant_type":"password","client_id":"administration","scope":"write","username":"admin","password":"shopware"}' 
    | jq -r .access_token)

curl -X POST https://shop.ejemplo.com/api/_action/df-image-optimizer/run-batch 
    -H "Authorization: Bearer $TOKEN" 
    -H "Content-Type: application/json" 
    -d '{"batchSize":200}'

Tablas creadas

df_image_optimizer

id                BINARY(16)   UUID
media_id          BINARY(16)   FK media.id ON DELETE CASCADE, UNIQUE
has_webp          TINYINT(1)
has_avif          TINYINT(1)
compressed        TINYINT(1)
original_size     BIGINT       Peso original en bytes
bytes_saved       BIGINT       Cumulativo ahorros
sales_channel_id  BINARY(16)   FK sales_channel.id ON DELETE SET NULL
optimized_at      DATETIME(3)
created_at        DATETIME(3)

df_image_optimizer_log

Diario opcional de errores. Solo lectura para depuración — sin purga automática.

Resolución de problemas

«El panel muestra AVIF: No disponible»

  • Si GD-only: verifique php -m | grep gd y php -i | grep AVIF. Se necesita PHP 8.1+ y GD compilado con --with-avif.
  • Si Imagick disponible: verifique php -r "print_r(Imagick::queryFormats('AVIF'));". ¿Vacío? Su Imagick no está compilado con libheif.
  • Fallback aceptable: deje AVIF desactivado y concéntrese en WebP.

«Las imágenes .webp se generan pero el storefront muestra JPEG»

sudo -u www-data setsid php bin/console theme:compile
sudo -u www-data setsid php bin/console cache:clear

Verifique con DevTools del navegador: abra la pestaña Red, recargue una página producto, inspeccione el tipo MIME — debería ver image/avif o image/webp.

«La subida de medios se ha vuelto lenta»

La conversión AVIF es CPU-intensiva. Desactive auto-optimización al subir y deje la tarea programada procesar en segundo plano.

«Las miniaturas .webp no se generan»

Verifique Procesar miniaturas en tarjeta General. Luego:

sudo -u www-data setsid php bin/console media:generate-thumbnails

«¿Cómo vaciar todos los archivos WebP/AVIF generados?»

cd /ruta/a/shopware
find public/media -name "*.webp" -delete
find public/media -name "*.avif" -delete

«Las URLs CDN no se aplican en todas partes»

Verifique el alcance configurado. URLs de origen para assets tema con alcance por defecto Solo medios son normales. Pase a Todos los recursos estáticos si su CDN está bien configurado.

Desinstalación

sudo -u www-data setsid php bin/console plugin:uninstall DfImageOptimizer
sudo -u www-data setsid php bin/console plugin:remove DfImageOptimizer

En la desinstalación, Shopware pregunta si conservar los datos de usuario:

  • Conservar (defecto): las tablas se mantienen en base.
  • No conservar: las dos tablas se eliminan (DROP TABLE).

En ambos casos, los archivos .webp y .avif en el filesystem permanecen.

Para ir más lejos

  • Monitorice su puntuación Core Web Vitals en Google Search Console
  • Pruebe con PageSpeed Insights antes/después — ganancia típica 20-40 puntos en móvil
  • Active también HTTP/2 o HTTP/3 lado servidor
  • Combine con caché página completa Shopware
¿Te ha resultado útil esta página?

¿Sigues atascado? Contacta con soporte