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.
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
- Ajustes → Sistema → Extensiones → Subir extensión
- Seleccione
DfImageOptimizer-1.0.0.zip - Haga clic en Instalar y luego Activar
- 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
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.jpg→foo.jpg.webp - Un hermano AVIF al lado:
foo.jpg→foo.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. |
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)
- Cree una Pull Zone en bunny.net con su URL de origen, por ejemplo
https://shop.ejemplo.com - BunnyCDN le da un hostname del tipo
shop-cdn.b-cdn.net - En la config del plugin, ponga:
https://shop-cdn.b-cdn.net - Elija el alcance Solo medios para empezar
- 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:
- Descarga de la imagen origen desde el filesystem público Shopware a archivo temporal local (
/tmp/dfimgopt_xxx.jpg) - Si Comprimir original activado: recompresión in-place con calidad configurada, eliminación metadatos si activada.
- Si WebP activado: conversión a WebP, escritura del hermano
foo.jpg.webp - Si AVIF activado y anchura ≤ anchura máxima: conversión a AVIF, escritura del hermano
foo.jpg.avif - Registro en tabla
df_image_optimizer - 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.
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:
- Consulta SQL vía LEFT JOIN sobre
df_image_optimizerpara identificar medios no optimizados - Procesa un lote de 50 imágenes (configurable)
- 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 gdyphp -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