Lazy Loading für Bilder und <iframe>-Elemente

Bilder und <iframe>-Elemente verbrauchen oft mehr Bandbreite als andere Ressourcentypen. Bei <iframe>-Elementen kann etwas zusätzliche Verarbeitungszeit für das Laden und Rendern der darin enthaltenen Seiten erforderlich sein.

Im Falle von Lazy Loading von Bildern kann das Zurückstellen des Ladens von Bildern, die sich außerhalb des ersten Darstellungsbereichs befinden, hilfreich sein, um Bandbreitenkonflikte für kritische Ressourcen im ersten Darstellungsbereich zu reduzieren. Dadurch kann der Largest Contentful Paint (LCP) einer Seite verbessert werden, wenn die Netzwerkverbindungen schwach sind. Außerdem kann die neu zugewiesene Bandbreite dazu beitragen, dass LCP-Kandidaten schneller geladen und bemalt werden.

Wenn es um <iframe>-Elemente geht, kann die Interaction to Next Paint (INP) einer Seite beim Start durch Lazy Loading verbessert werden. Dies liegt daran, dass ein <iframe> ein vollständig separates HTML-Dokument mit eigenen Unterressourcen ist. <iframe>-Elemente können zwar in einem separaten Prozess ausgeführt werden, es ist jedoch nicht ungewöhnlich, dass sie sich einen Prozess mit anderen Threads teilen. Dies kann zu Bedingungen führen, in denen Seiten weniger schnell auf Nutzereingaben reagieren.

Daher lohnt es sich, das Laden von nicht sichtbaren Elementen und <iframe>-Elementen aufzuschieben, und sie erfordert einen relativ geringen Aufwand, um eine hinreichend gute Leistung zu erzielen. In diesem Modul wird erläutert, wie Lazy Loading für diese beiden Arten von Elementen verwendet wird, um die Nutzererfahrung während der kritischen Startphase der Seite zu beschleunigen und zu verbessern.

Lazy Loading von Bildern mit dem Attribut loading

Das loading-Attribut kann <img>-Elementen hinzugefügt werden, um dem Browser mitzuteilen, wie sie geladen werden sollen:

  • "eager" informiert den Browser darüber, dass das Bild sofort geladen werden soll, auch wenn es sich außerhalb des ersten Darstellungsbereichs befindet. Dies ist auch der Standardwert für das Attribut loading.
  • "lazy" verzögert das Laden eines Bildes, bis es sich innerhalb einer festgelegten Entfernung vom sichtbaren Darstellungsbereich befindet. Dieser Abstand variiert je nach Browser, ist jedoch oft so groß, dass das Bild geladen wird, wenn der Nutzer dorthin scrollt.

Wenn Sie das <picture>-Element verwenden, sollte das loading-Attribut trotzdem auf das untergeordnete <img>-Element angewendet werden, nicht auf das <picture>-Element selbst. Dies liegt daran, dass das <picture>-Element ein Container ist, der zusätzliche <source>-Elemente enthält, die auf verschiedene mögliche Bildkandidaten verweisen. Der vom Browser ausgewählte Kandidat wird direkt auf das untergeordnete <img>-Element angewendet.

Kein Lazy Loading von Bildern, die sich im ersten Darstellungsbereich befinden

Sie sollten das Attribut loading="lazy" nur <img>-Elementen hinzufügen, die sich außerhalb des ersten Darstellungsbereichs befinden. Es kann jedoch schwierig sein, die genaue Position eines Elements relativ innerhalb des Darstellungsbereichs zu kennen, bevor die Seite gerendert wird. Dabei müssen unterschiedliche Größen, Seitenverhältnisse und Geräte für den Darstellungsbereich berücksichtigt werden.

Ein Desktop-Darstellungsbereich kann sich beispielsweise stark von einem Darstellungsbereich auf einem Mobiltelefon unterscheiden, da er mehr vertikalen Bereich rendert, sodass Bilder unter Umständen in den ersten Darstellungsbereich passen, der im ersten Darstellungsbereich auf einem physisch kleineren Gerät nicht zu sehen wäre. Tablets, die im Hochformat verwendet werden, bieten ebenfalls viel vertikalen Platz, möglicherweise sogar mehr als einige Desktop-Geräte.

Es gibt jedoch auch Fälle, in denen es ganz klar ist, die Anwendung von loading="lazy" zu vermeiden. Du solltest auf jeden Fall das Attribut loading="lazy" aus <img>-Elementen weglassen, wenn es sich um Hero-Images oder andere Bildanwendungsfälle handelt, in denen <img>-Elemente auf beliebigen Geräten „above the fold“ oder oben im Layout erscheinen. Dies ist vor allem bei Bildern wichtig, die wahrscheinlich LCP-Kandidaten sind.

Bei Lazy-Loading-Bildern muss gewartet werden, bis das Layout des Browsers fertiggestellt ist. Andernfalls kann nicht festgestellt werden, ob sich die endgültige Position des Bildes innerhalb des Darstellungsbereichs befindet. Wenn also ein <img>-Element im sichtbaren Darstellungsbereich ein loading="lazy"-Attribut hat, wird es erst angefordert, nachdem der gesamte CSS-Code heruntergeladen, geparst und auf die Seite angewendet wurde, und nicht abgerufen, sobald es vom Vorlade-Scanner im Roh-Markup erkannt wurde.

Da das loading-Attribut des <img>-Elements in allen gängigen Browsern unterstützt wird, ist für das Lazy Loading von Bildern kein JavaScript erforderlich. Das Hinzufügen von zusätzlichem JavaScript zu einer Seite, um Funktionen bereitzustellen, die der Browser bereits bietet, wirkt sich auf andere Aspekte der Seitenleistung wie INP aus.

Lazy Loading für Bilder – Demo

<iframe>-Elemente für Lazy Loading

Durch Lazy Loading von <iframe>-Elementen, bis sie im Darstellungsbereich sichtbar sind, können erhebliche Daten eingespart und das Laden kritischer Ressourcen verbessert werden, die zum Laden der Seite auf oberster Ebene erforderlich sind. Da es sich bei <iframe>-Elementen im Wesentlichen um vollständige HTML-Dokumente handelt, die in einem Dokument auf oberster Ebene geladen werden, können sie eine beträchtliche Anzahl von Unterressourcen – insbesondere JavaScript – enthalten, die die INP einer Seite stark beeinflussen können, wenn die Aufgaben innerhalb dieser Frames viel Verarbeitungszeit erfordern.

Einbettungen von Drittanbietern werden häufig für <iframe>-Elemente verwendet. Eingebettete Videoplayer oder Beiträge in sozialen Medien verwenden beispielsweise häufig <iframe>-Elemente und erfordern oft eine beträchtliche Anzahl von Unterressourcen, was auch zu einem Bandbreitenkonflikt für die Ressourcen der obersten Ebene führen kann. Beim Lazy Loading der Einbettung eines YouTube-Videos werden beispielsweise beim ersten Seitenaufbau über 500 KiB eingespart. Beim Lazy Loading des Facebook-Plug-ins Gefällt mir“ werden mehr als 200 KiB eingespart – größtenteils JavaScript.

Wenn <iframe> auf einer Seite mit Scrollen sichtbar ist, solltest du in jedem Fall ein Lazy Loading in Betracht ziehen, wenn es nicht unbedingt vorab geladen werden muss, da dies die Nutzererfahrung erheblich verbessern kann.

Das Attribut loading für <iframe>-Elemente

Das loading-Attribut von <iframe>-Elementen wird auch von allen gängigen Browsern unterstützt. Die Werte für das Attribut loading und ihr Verhalten sind dieselben wie bei <img>-Elementen, die das Attribut loading verwenden:

  • "eager" ist der Standardwert. Damit wird der Browser angewiesen, den HTML-Code des <iframe>-Elements und seine Unterressourcen sofort zu laden.
  • "lazy" verzögert das Laden des HTML-Elements des <iframe>-Elements und seiner Unterressourcen, bis es innerhalb einer vordefinierten Entfernung vom Darstellungsbereich liegt.

Lazy Loading von iFrames – Demo

Fassadenreinigung

Anstatt eingebettete Inhalte sofort während des Seitenaufbaus zu laden, können Sie sie bei Bedarf als Reaktion auf eine Nutzerinteraktion laden. Dazu kann so lange ein Bild oder ein anderes geeignetes HTML-Element angezeigt werden, bis der Nutzer damit interagiert. Sobald der Nutzer mit dem Element interagiert, können Sie es durch die Einbettung eines Drittanbieters ersetzen. Diese Technik wird als Fassade bezeichnet.

Ein häufiger Anwendungsfall für Fassaden sind Videoeinbettungen von Drittanbieterdiensten, bei denen zusätzlich zum Videoinhalt viele zusätzliche und potenziell teure Unterressourcen wie JavaScript geladen werden müssen. In einem solchen Fall – es sei denn, die automatische Wiedergabe eines Videos muss legitim sein –, müssen Nutzer vor der Wiedergabe mit ihnen interagieren, indem sie auf die Wiedergabeschaltfläche klicken.

Dies ist eine hervorragende Gelegenheit, ein statisches Bild zu zeigen, das der Videoeinbettung optisch ähnelt, und dabei erheblich Bandbreite zu sparen. Sobald der Nutzer auf das Bild klickt, wird es durch die eigentliche Einbettung <iframe> ersetzt, wodurch der HTML-Code des Drittanbieter-<iframe>-Elements und seine Unterressourcen heruntergeladen werden.

Ein weiterer wichtiger Vorteil: Wenn der Nutzer das Video nie wiedergibt, werden die für die Bereitstellung erforderlichen Ressourcen auch nicht heruntergeladen. Dies ist ein gutes Muster, da dadurch sichergestellt wird, dass der Nutzer nur das herunterlädt, was er tatsächlich möchte, ohne dabei möglicherweise fehlerhafte Annahmen zu den Anforderungen des Nutzers anzunehmen.

Chat-Widgets sind ein weiteres hervorragendes Anwendungsbeispiel für die Fassadentechnik. Die meisten Chat-Widgets laden eine große Menge an JavaScript-Code herunter, der sich negativ auf den Seitenaufbau und die Reaktionsfähigkeit auf Nutzereingaben auswirken kann. Wie beim Laden von Inhalten im Vorfeld fallen die Kosten während der Ladezeit an. Im Fall eines Chat-Widgets hat jedoch nicht jeder Nutzer die Absicht, mit ihm zu interagieren.

Bei einer Fassade hingegen ist es möglich, die Schaltfläche „Chat starten“ eines Drittanbieters durch eine gefälschte Schaltfläche zu ersetzen. Sobald der Nutzer sinnvoll damit interagiert – z. B. einen Zeiger darüber für einen angemessenen Zeitraum halten oder darauf klicken –, wird das tatsächliche, funktionale Chat-Widget an der Stelle platziert, wenn der Nutzer es benötigt.

Es ist zwar durchaus möglich, eigene Fassaden zu erstellen, aber es gibt auch Open-Source-Optionen für gängige Drittanbieter wie lite-youtube-embed für YouTube-Videos, lite-vimeo-embed für Vimeo-Videos und das React-Livechat-Ladeprogramm für Chat-Widgets.

JavaScript-Bibliotheken für Lazy Loading

Lazy Loading von <video>-Elementen, <video>-Element-poster-Bildern, von der CSS-Eigenschaft background-image geladenen Bildern oder anderen nicht unterstützten Elementen ist eine JavaScript-basierte Lösung für Lazy Loading wie Lazysizes oder yall.js, da Lazy Loading für diese Arten von Ressourcen keine Funktion auf Browserebene ist.

Insbesondere die automatische Wiedergabe und Schleifen von <video>-Elementen ohne Audiotrack sind deutlich effizienter als animierte GIFs, die oft um ein Vielfaches größer sein können als eine Videoressource mit gleichwertiger visueller Qualität. Dennoch können diese Videos in Bezug auf die Bandbreite von erheblicher Bedeutung sein. Lazy Loading ist also eine zusätzliche Optimierung, mit der sich die Verschwendung von Bandbreite reduzieren lässt.

Die meisten dieser Bibliotheken verwenden die Intersection Observer API und zusätzlich die Mutation Observer API, wenn sich der HTML-Code einer Seite nach dem anfänglichen Laden ändert, um zu erkennen, wann ein Element in den Darstellungsbereich des Nutzers gelangt. Wenn das Bild sichtbar ist oder sich dem Darstellungsbereich nähert, ersetzt die JavaScript-Bibliothek das nicht standardmäßige Attribut (häufig data-src oder ein ähnliches Attribut) durch das richtige Attribut, z. B. src.

Angenommen, Sie haben ein Video, das ein animiertes GIF ersetzt, möchten es aber mit einer JavaScript-Lösung per Lazy Loading laden. Dies ist mit yall.js mit dem folgenden Markup-Muster möglich:

<!-- The autoplay, loop, muted, and playsinline attributes are to
     ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
  <source data-src="video.webm" type="video/webm">
  <source data-src="video.mp4" type="video/mp4">
</video>

Standardmäßig beobachtet „yall.js“ alle infrage kommenden HTML-Elemente mit einer Klasse von "lazy". Nachdem yall.js auf der Seite geladen und ausgeführt wurde, wird das Video erst geladen, wenn der Nutzer in den Darstellungsbereich scrollt. An dieser Stelle werden die data-src-Attribute in den untergeordneten <source>-Elementen des <video>-Elements gegen src-Attribute ausgetauscht. Dadurch wird eine Anfrage zum Herunterladen des Videos und zum automatischen Starten der Wiedergabe gesendet.

Wissen testen

Welcher ist der Standardwert für das Attribut loading für die Elemente <img> und <iframe>?

"eager"
Richtig!
"lazy"
Versuche es noch einmal.

Wann sind auf JavaScript basierende Lazy Loading-Lösungen sinnvoll?

Für jede Ressource, für die Lazy Loading verwendet werden kann.
Versuche es noch einmal.
Bei Ressourcen, bei denen das Attribut loading nicht unterstützt wird, z. B. bei automatisch wiedergegebenen Videos, die animierte Bilder ersetzen sollen, oder beim Lazy Loading des Posterbilds eines <video>-Elements.
Richtig!

Wann ist eine Fassade eine nützliche Technik?

Für Einbettungen von Drittanbietern, die unabhängig von den Anforderungen des Nutzers große Daten nutzen.
Versuche es noch einmal.
Bei Einbettungen von Drittanbietern, bei denen die zum Laden erforderlichen Ressourcen nicht nur umfangreich sind, sondern auch mit hoher Wahrscheinlichkeit nicht alle Nutzer verwenden, ist eine Interaktion möglich.
Richtig!

Nächster Schritt: Prefetching und Pre-Rendering

Da du jetzt mit Lazy Loading von Bildern und <iframe>-Elementen vertraut bist, kannst du dafür sorgen, dass Seiten schneller geladen werden, während gleichzeitig die Anforderungen deiner Nutzer berücksichtigt werden. Es gibt jedoch Fälle, in denen ein spekulatives Laden von Ressourcen wünschenswert sein kann. Im nächsten Modul erfahren Sie mehr über Prefetch und Pre-Rendering und darüber, wie diese Verfahren – wenn sie sorgfältig eingesetzt werden – das Navigieren zu nachfolgenden Seiten erheblich beschleunigen können, indem sie im Voraus geladen werden.