srcset, sizes und Art Direction richtig kombinieren
Ein einzelnes img-Tag mit fester Breite reicht für kaum ein modernes Layout aus. Wir zeigen, wie srcset und sizes im Hyvä-Theme korrekt erzeugt werden, wann ein picture-Element für echte Art Direction nötig ist und wie beides mit Magentos Bild-Resize-Cache zusammenspielt.
Inhaltsverzeichnis
- 1. Warum ein einzelnes img-Tag für responsive Layouts nicht reicht
- 2. srcset und sizes: die Mechanik im Hyvä-Kontext
- 3. Wo Hyvä bereits srcset generiert und wo nicht
- 4. Eigene ViewModel-Logik für mehrere Bildgrößen
- 5. Das picture-Element für echte Art Direction
- 6. Zusammenspiel mit Magentos Bild-Resize-Cache
- 7. On-the-fly-Generierung versus Vorab-Generierung via Cron
- 8. Performance-Messung: Auswirkung auf LCP und Bandbreite
- 9. Praxis-Checkliste zur Einführung
- 10. Zusammenfassung
- 11. FAQ
1. Warum ein einzelnes img-Tag für responsive Layouts nicht reicht
Ein img-Tag mit einer einzigen, festen Bildquelle liefert auf einem großen Desktop-Monitor entweder ein unnötig großes Bild oder auf einem Mobilgerät ein unnötig kleines. Beides kostet entweder Bandbreite oder Bildschärfe, und beides wirkt sich messbar auf den Largest Contentful Paint aus, gerade bei Produktbildern, die häufig das größte sichtbare Element oberhalb des Falts sind.
Das Problem verschärft sich zusätzlich durch unterschiedliche Pixeldichten: Ein Bildschirm mit doppelter Pixeldichte benötigt bei gleicher angezeigter Größe die doppelte Auflösung, um scharf zu wirken. Ein einzelnes Bild kann diesen Kompromiss zwischen Dateigröße und Schärfe grundsätzlich nicht auflösen, weshalb srcset und sizes für jedes ernsthafte Hyvä-Frontend Pflicht sind, nicht optional. Gerade bei Magento-Katalogen mit sehr unterschiedlichen Produktbildgrößen, von schmalen Ersatzteil-Fotos bis zu großformatigen Lifestyle-Aufnahmen, zeigt sich der Effekt einer fehlenden responsiven Bildstrategie besonders deutlich in den Performance-Messwerten.
2. srcset und sizes: die Mechanik im Hyvä-Kontext
Das srcset-Attribut listet mehrere Bildvarianten mit ihrer jeweiligen tatsächlichen Pixelbreite auf, gekennzeichnet mit dem w-Deskriptor. Das sizes-Attribut beschreibt dagegen, wie breit das Bild im Layout bei welcher Viewport-Breite tatsächlich dargestellt wird. Erst aus der Kombination beider Angaben berechnet der Browser, welche Bildvariante er tatsächlich lädt, und zwar bevor das CSS-Layout final feststeht, weshalb die sizes-Angabe möglichst präzise dem tatsächlichen Layout entsprechen muss.
In einem Hyvä-Theme mit Tailwind-basiertem Grid ergibt sich die sizes-Angabe direkt aus den verwendeten Breakpoint-Klassen. Zeigt eine Produktkachel bei großen Viewports ein Viertel der Breite und bei kleinen Viewports die volle Breite, muss genau diese Logik als sizes-Attribut formuliert werden, sonst lädt der Browser trotz korrektem srcset eine unpassende Variante.
<img
src="https://shop.example.com/media/catalog/product/cache/.../product-800.jpg"
srcset="
.../product-400.jpg 400w,
.../product-800.jpg 800w,
.../product-1200.jpg 1200w
"
sizes="(min-width: 1024px) 25vw, (min-width: 640px) 50vw, 100vw"
loading="lazy"
alt="Produktname"
>
3. Wo Hyvä bereits srcset generiert und wo nicht
Die Kern-Templates von Hyvä für Produktlisten und Kategorieseiten erzeugen bereits ein srcset für die vordefinierten Bildtypen wie category_page_grid oder product_page_image_large, basierend auf den in view.xml konfigurierten Breiten. Für viele Standardanwendungen ist das ausreichend, weil die dort hinterlegten Breiten typische Grid-Layouts abdecken.
Sobald ein eigenes, von den Magento-Standard-Bildtypen abweichendes Layout zum Einsatz kommt, etwa eine dreispaltige Produktkachel mit eigenen Breakpoints oder ein Hero-Banner mit ungewöhnlichem Seitenverhältnis, reicht die Standard-Konfiguration meist nicht mehr aus. In diesem Fall müssen zusätzliche Bildbreiten in der view.xml ergänzt und die srcset-Erzeugung im entsprechenden ViewModel oder Template angepasst werden.
4. Eigene ViewModel-Logik für mehrere Bildgrößen
Für eigene Bildbreiten empfiehlt sich ein dediziertes ViewModel, das über den ImageFactory-Service mehrere Größen für dieselbe Bildquelle erzeugt und als fertiges srcset-Attribut an das Template zurückgibt. Damit bleibt die Logik zur Bildgrößen-Generierung an einer zentralen Stelle testbar, statt in mehreren Templates dupliziert zu werden.
Wichtig ist, dass jede zusätzliche Breite eine eigene Kombination aus Bildtyp und Zielgröße im Resize-Cache erzeugt. Eine zu granulare Abstufung, etwa fünf oder sechs Breiten für ein und dasselbe Bild, erhöht zwar die theoretische Passgenauigkeit, aber auch die Anzahl der zu generierenden und zu speichernden Cache-Dateien erheblich, ohne dass der wahrnehmbare Qualitätsgewinn ab einer gewissen Abstufung noch spürbar wäre.
<?php
declare(strict_types=1);
namespace Mironsoft\Core\ViewModel;
use Magento\Catalog\Helper\Image as ImageHelper;
use Magento\Catalog\Model\Product;
use Magento\Framework\View\Element\Block\ArgumentInterface;
/**
* Erzeugt ein srcset-Attribut mit mehreren Bildbreiten für ein Produktbild.
*/
class ResponsiveImage implements ArgumentInterface
{
private const WIDTHS = [400, 800, 1200];
public function __construct(private readonly ImageHelper $imageHelper)
{
}
/**
* Baut den srcset-String für einen Produkt- und Bildtyp.
*
* @param Product $product
* @param string $imageType
* @return string
*/
public function getSrcSet(Product $product, string $imageType): string
{
$parts = [];
foreach (self::WIDTHS as $width) {
$url = $this->imageHelper
->init($product, $imageType)
->constrainOnly(true)
->keepAspectRatio(true)
->resize($width)
->getUrl();
$parts[] = sprintf('%s %dw', $url, $width);
}
return implode(', ', $parts);
}
}
5. Das picture-Element für echte Art Direction
srcset und sizes lösen ausschließlich das Auflösungsproblem: Dieselbe Bildkomposition wird nur in unterschiedlichen Größen ausgeliefert. Soll sich dagegen der Bildausschnitt selbst je nach Viewport unterscheiden, etwa ein breites Querformat auf Desktop und ein enger zugeschnittenes Hochformat auf Mobilgeräten, reicht srcset nicht aus. Dafür ist das picture-Element mit mehreren source-Tags und media-Bedingungen erforderlich.
Jede source-Zeile definiert dabei eine eigene Bildquelle für eine bestimmte Viewport-Bedingung, und der Browser wählt die erste zutreffende Bedingung von oben nach unten aus. Das abschließende img-Tag dient als Fallback für Browser ohne picture-Unterstützung und sollte deshalb immer eine sinnvolle Standardvariante enthalten, meist die mobile Variante als konservativste Wahl.
<picture>
<source
media="(min-width: 1024px)"
srcset=".../hero-wide-1600.jpg 1600w, .../hero-wide-2400.jpg 2400w"
sizes="100vw"
>
<source
media="(min-width: 640px)"
srcset=".../hero-square-1000.jpg 1000w"
sizes="100vw"
>
<img
src=".../hero-portrait-800.jpg"
loading="lazy"
alt="Kampagnenmotiv"
>
</picture>
6. Zusammenspiel mit Magentos Bild-Resize-Cache
Jede angeforderte Kombination aus Originalbild, Bildtyp und Zielbreite erzeugt beim ersten Aufruf eine neue Datei unterhalb von pub/media/catalog/product/cache. Bei konsequenter Nutzung von srcset über mehrere Breiten und zusätzlich picture-basierter Art Direction mit eigenen Bildquellen vervielfacht sich die Anzahl dieser Cache-Dateien schnell, insbesondere bei großen Produktkatalogen mit tausenden Artikeln.
Diese Vervielfachung ist grundsätzlich kein Problem, solange sie bewusst eingeplant wird. Kritisch wird es, wenn Breiten unkoordiniert in mehreren Templates unabhängig voneinander definiert werden und dadurch für dasselbe Bild deutlich mehr Varianten entstehen als tatsächlich im Layout vorkommen. Eine zentrale Konstanten-Definition für erlaubte Breiten, wie im ViewModel-Beispiel oben, verhindert diese unkontrollierte Vervielfachung.
7. On-the-fly-Generierung versus Vorab-Generierung via Cron
Standardmäßig generiert Magento fehlende Bildvarianten beim ersten Zugriff on-the-fly, was den allerersten Seitenaufruf für eine bestimmte Bildgröße spürbar verlangsamt. Für Shops mit planbarem Produktkatalog, etwa nach einem größeren Import, lohnt sich stattdessen eine Vorab-Generierung über den Befehl catalog:images:resize, der alle konfigurierten Bildtypen und Breiten im Voraus erzeugt.
Für neu angelegte Produkte, die zwischen zwei Cron-Läufen live gehen, bleibt weiterhin die on-the-fly-Generierung als Fallback aktiv. In der Praxis empfiehlt sich deshalb eine Kombination: catalog:images:resize nach jedem größeren Import oder nach jeder view.xml-Änderung ausführen, die on-the-fly-Generierung aber als Sicherheitsnetz für Einzelfälle nicht deaktivieren.
bin/magento catalog:images:resize
bin/cache-clean
8. Performance-Messung: Auswirkung auf LCP und Bandbreite
Der messbare Effekt korrekt konfigurierter srcset-Angaben zeigt sich am deutlichsten im Largest Contentful Paint, insbesondere auf Mobilgeräten mit begrenzter Bandbreite. Ein Produktbild, das ohne srcset in voller Desktop-Auflösung auf ein Smartphone ausgeliefert wird, kann den LCP-Wert leicht um mehrere hundert Millisekunden verschlechtern, allein durch die zusätzliche Übertragungszeit.
Für die Messung eignet sich ein Vergleich der Network-Tab-Daten in den Chrome DevTools vor und nach der srcset-Einführung, insbesondere die tatsächlich übertragene Dateigröße auf einem simulierten Mobilgerät. Diese konkrete Zahl lässt sich deutlich einfacher kommunizieren als ein abstrakter Lighthouse-Score und zeigt den Effekt unmittelbar in übertragenen Kilobyte.
9. Praxis-Checkliste zur Einführung
Der Einstieg gelingt am strukturiertesten über eine feste Reihenfolge: zunächst die tatsächlich verwendeten Layout-Breiten pro Breakpoint dokumentieren, danach die passenden sizes-Werte daraus ableiten, dann die benötigten Bildbreiten in der view.xml oder im ViewModel definieren und erst zum Schluss prüfen, ob für einzelne Bereiche überhaupt echte Art Direction mit einem picture-Element nötig ist.
Die folgende Tabelle vergleicht die vorgestellten Techniken hinsichtlich Aufwand und Wirkung, damit sich Teams zunächst auf die Maßnahme mit dem besten Verhältnis konzentrieren können, statt alle Techniken gleichzeitig einzuführen und dabei den Überblick über die Cache-Auswirkungen zu verlieren.
| Technik | Löst welches Problem | Cache-Auswirkung | Aufwand |
|---|---|---|---|
| srcset mit w-Deskriptor | Falsche Auflösung je Viewport | Eine Datei pro definierter Breite | Gering |
| sizes-Attribut | Falsche Browser-Berechnung der Anzeigebreite | Keine zusätzliche Cache-Datei | Gering |
| picture mit mehreren source | Falscher Bildausschnitt je Viewport | Mehrfache Dateien pro Breakpoint | Mittel |
| Vorab-Resize via Cron | Langsamer erster Seitenaufruf | Reduziert on-the-fly-Generierung | Mittel, einmalig einzurichten |
| Zentrale Breiten-Konstante im ViewModel | Unkoordinierte Breiten-Vervielfachung | Begrenzt Cache-Wachstum gezielt | Gering |
Mironsoft
Hyvä-Theme-Entwicklung und Luma-Migration
Noch auf Luma unterwegs oder ein Hyvä-Theme, das nicht rund läuft?
Wir entwickeln Hyvä-Themes für Magento von Grund auf oder migrieren bestehende Luma-Shops sauber, mit Tailwind CSS, Alpine.js und ohne unnötiges JavaScript-Gepäck.
Luma-zu-Hyvä-Migration
Bestehenden Shop strukturiert und ohne Funktionsverlust auf Hyvä umstellen.
Custom-Theme-Entwicklung
Individuelles Hyvä-Theme nach Design-Vorgaben von Grund auf umsetzen.
Performance-Optimierung
Core Web Vitals und Ladezeiten im Hyvä-Frontend gezielt verbessern.
10. Zusammenfassung
Responsive Bilder im Hyvä-Theme: Das Wichtigste auf einen Blick
Grundregel
srcset löst das Auflösungsproblem, picture löst das Art-Direction-Problem, beide haben unterschiedliche Aufgaben.
sizes-Präzision
Das sizes-Attribut muss exakt der tatsächlichen Tailwind-Grid-Logik entsprechen, sonst lädt der Browser die falsche Variante.
Cache-Wachstum
Jede zusätzliche Breite vervielfacht die Resize-Cache-Dateien, zentrale Breiten-Konstanten verhindern Wildwuchs.
Vorab-Generierung
catalog:images:resize nach Import oder view.xml-Änderung vermeidet einen langsamen ersten Seitenaufruf.