Herausforderungen mit responsiven Bildern
Die Optimierung von Hero-Bildern ist entscheidend für die Web-Performance und das Nutzererlebnis. Dieser Artikel befasst sich mit Strategien für responsive Bilder – srcset, multiple images und <picture>. Außerdem werden Best Practices für schnelles Laden, Klarheit und Bandbreiteneffizienz auf allen Geräten vorgestellt.
Herausforderungen mit responsiven Bildern
Für Performance, SEO und Nutzererlebnis sollten Seiten so schnell wie möglich laden. Bilder sind oft die größten Bandbreitenfresser. Wir wollen Bilder so klein wie möglich halten und nur Dateien laden, die zur aktuellen Bildschirmbreite und Pixeldichte passen. Auf responsiven Seiten können Bilder jedoch unscharf oder unnötig groß wirken, wenn sich die Seitenverhältnisse über Breakpoints hinweg ändern. Das ist besonders häufig bei Hero-Bildern der Fall. Wir nutzen sie als Beispiel, um mögliche Lösungen vorzustellen.
Responsive Bilder in HTML verwenden
Ein häufiger Ansatz ist, ein <img>-Element mit sizes und srcset zu verwenden.
<img
srcset="<https://example.com/hero-480.jpg> 480w, <https://example.com/hero-1600.jpg> 1600w"
sizes="100vw"
src="<https://example.com/hero.jpg>"
alt="hero"
/>
srcset definiert eine Menge an Bildkandidaten, aus denen der Browser je nach intrinsischer Breite auswählen kann.
sizes legt Medienbedingungen fest und sagt dem Browser, welche Breite aus srcset unter welcher Bedingung zu erwarten ist.
Mit Next.js können wir die Image-Komponente und einen Loader verwenden, um srcset und sizes automatisch zu generieren:
import Image from "next/image";
const imageLoader = ({ src, width, quality }) => {
return `{{<https://example.com/${src}>}}?w=${width}&q=${quality || 75}`;
};
export default function Hero() {
return <Image fill loader={imageLoader} src="hero.jpg" sizes="100vw" alt="Hero"/>;
}
)
)
Aus den Bildern sehen wir das Problem: Das benötigte Seitenverhältnis hängt oft von der Bildschirmgröße ab. Auf großen Displays ist das Seitenverhältnis häufig breiter, während dasselbe Verhältnis auf kleinen Geräten meist unpassend wirkt. Erhöhen wir die Höhe, wird das Bild gestreckt und anschließend beschnitten und dadurch unscharf. Alternativ müssten wir auf Mobilgeräten ein deutlich größeres Bild laden.
Mehrere Bildelemente mit Anzeige‑Toggles
Wir können separate Mobile- und Desktop-Bilder rendern und die Sichtbarkeit über CSS‑Klassen steuern.
return (
<>
<Image
fill
loader={imageLoader}
src="mobile-hero.jpg"
sizes="100vw"
className="md:hidden"
alt="Hero mobile"
/>
<Image
fill
loader={imageLoader}
src="desktop-hero.jpg"
sizes="100vw"
className="max-md:hidden"
alt="Hero desktop"
/>
</>)
Das funktioniert: Auf Mobilgeräten wird mobile-hero angezeigt und bleibt klar, auf dem Desktop erscheint desktop-hero. Wird eine Image‑Komponente versteckt, wird ihr Bild nicht heruntergeladen. Das spart Bandbreite.
)
)
Es gibt jedoch einen Nachteil: Als Hero sollte das Bild für den First Contentful Paint (FCP) nicht lazy‑geladen werden, sondern Priorität haben. Andernfalls beginnt der Download erst nach der Layoutberechnung, also zu spät. Deaktiviert man das Lazy‑Loading für beide Bilder, könnten beide heruntergeladen werden, was Bandbreite verschwendet.
Die bessere Lösung: <picture> mit mehreren <source>‑Elementen
Verwende <picture> und <source> mit Media Queries. Der Browser lädt nur die Quelle, die zum aktuellen Viewport passt.
<picture>
<!-- Zuerst Desktop -->
<source
srcset="/images/desktop-hero-1600.jpg 1600w, /images/desktop-hero-1200.jpg 1200w"
media="(min-width: 768px)"
sizes="(min-width: 1440px) 1600px, 100vw"
/>
<!-- Mobile-Fallback -->
<source
srcset="/images/mobile-hero-800.jpg 800w, /images/mobile-hero-480.jpg 480w"
media="(max-width: 767px)"
sizes="100vw"
/>
<img
src="fallback-image.jpg"
sizes="100vw"
alt="Hero image"
decoding="async"
fetchpriority="high"
/>
</picture>
In jedem <source> können wir zusätzlich sizes nutzen, um zu steuern, welche Ressource geladen wird. Das <img>‑Element dient als Fallback und sollte auf eine sinnvolle Standardvariante zeigen. Für das zentrale Hero‑Bild sollten wir fetchpriority auf "high" setzen, um den FCP zu verbessern. In Next.js können wir statt <img> auch <Image> innerhalb von <picture> nutzen, die <source>‑Elemente bleiben gleich.
Fazit
Von den drei Ansätzen bevorzuge ich <picture>, wenn sich das Seitenverhältnis über Breakpoints deutlich ändert. Die Developer‑Experience ist vielleicht etwas weniger bequem als bei vorgefertigten Komponenten wie der Next.js‑Image‑Komponente, aber das Nutzererlebnis ist besser: Es wird nur die notwendige Datenmenge geladen und die Bildschärfe bleibt erhalten.
Im Zeitalter der KI ist das Zusammenstellen einer Seite einfach, aber eine reibungslose, ressourceneffiziente Website entsteht durch Liebe zum Detail – selbst bei einem „einfachen“ Hero‑Bild. Deshalb liefern Übergaben an erfahrene Profis oft die besten Ergebnisse.
)
)
)
)
)
)
)
)
)