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

Bilder und <iframe>-Elemente verbrauchen oft mehr Bandbreite als andere Arten von Ressourcen. Bei <iframe>-Elementen kann das Laden und Rendern der darin enthaltenen Seiten ziemlich viel zusätzliche Verarbeitungszeit in Anspruch nehmen.

Beim Lazy-Loading von Bildern kann das Aufschieben des Ladens von Bildern, die sich außerhalb des ursprünglichen Darstellungsbereichs befinden, dazu beitragen, Bandbreitenkonflikte für kritischere Ressourcen innerhalb des ursprünglichen Darstellungsbereichs zu reduzieren. Dies kann in einigen Fällen, in denen die Netzwerkverbindungen schlecht sind, den LCP-Wert (Largest Contentful Paint) einer Seite verbessern. Die neu zugewiesene Bandbreite kann dazu beitragen, dass LCP-Kandidaten schneller geladen und dargestellt werden.

Bei <iframe>-Elementen kann der Wert „Interaction to Next Paint“ (INP) einer Seite beim Start durch Lazy Loading verbessert werden. Das liegt daran, dass ein <iframe> ein völlig separates HTML-Dokument mit eigenen Unterressourcen ist. <iframe>-Elemente können in einem separaten Prozess ausgeführt werden, es ist aber nicht ungewöhnlich, dass sie einen Prozess mit anderen Threads teilen. Dies kann dazu führen, dass Seiten weniger reaktionsschnell auf Nutzereingaben reagieren.

Daher ist es sinnvoll, das Laden von Bildern und <iframe>-Elementen außerhalb des Bildschirms zu verschieben. Das erfordert nur wenig Aufwand und bringt einen relativ guten Leistungsgewinn. In diesem Modul erfahren Sie, wie Sie diese beiden Arten von Elementen mit Lazy Load laden, um die Nutzerfreundlichkeit während der kritischen Startphase der Seite zu verbessern.

Lazy Loading von Bildern mit dem loading-Attribut

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

  • "eager" informiert den Browser, dass das Bild sofort geladen werden soll, auch wenn es sich außerhalb des ursprünglichen Darstellungsbereichs befindet. Dies ist auch der Standardwert für das Attribut loading.
  • "lazy" verzögert das Laden eines Bildes, bis es sich in einem festgelegten Abstand vom sichtbaren Darstellungsbereich befindet. Dieser Abstand variiert je nach Browser, ist aber oft so groß, dass das Bild geladen ist, wenn der Nutzer zu ihm scrollt.

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

Bilder, die sich im ersten Darstellungsbereich befinden, nicht per Lazy Loading laden

Das loading="lazy"-Attribut sollte nur <img>-Elementen hinzugefügt werden, die sich außerhalb des ursprünglichen Darstellungsbereichs befinden. Es kann jedoch schwierig sein, die genaue Position eines Elements im Verhältnis zum Darstellungsbereich zu ermitteln, bevor die Seite gerendert wird. Es müssen unterschiedliche Darstellungsbereiche, Seitenverhältnisse und Geräte berücksichtigt werden.

Ein Desktop-Darstellungsbereich kann sich beispielsweise stark von einem Darstellungsbereich auf einem Smartphone unterscheiden, da er mehr vertikalen Raum bietet. So können Bilder im ursprünglichen Darstellungsbereich angezeigt werden, die auf einem physisch kleineren Gerät nicht zu sehen wären. Tablets, die im Hochformat verwendet werden, bieten auch eine beträchtliche Menge an vertikalem Platz, möglicherweise sogar mehr als einige Desktop-Geräte.

Es gibt jedoch einige Fälle, in denen es ziemlich klar ist, dass Sie loading="lazy" nicht anwenden sollten. Das loading="lazy"-Attribut sollte beispielsweise bei Hero-Bildern oder anderen Bildanwendungsfällen, bei denen <img>-Elemente auf allen Geräten wahrscheinlich über dem Falz oder oben im Layout erscheinen, unbedingt aus <img>-Elementen entfernt werden. Das ist noch wichtiger für Bilder, die wahrscheinlich für die LCP-Funktion infrage kommen.

Bei Bildern, die mit Lazy Loading geladen werden, muss der Browser warten, bis das Layout fertig ist, um zu wissen, ob sich die endgültige Position des Bilds im Viewport befindet. Das bedeutet, dass ein <img>-Element im sichtbaren Darstellungsbereich, das ein loading="lazy"-Attribut hat, erst nachdem das gesamte CSS heruntergeladen, geparst und auf die Seite angewendet wurde, angefordert wird. Andernfalls wird es abgerufen, sobald es vom Preloader im Roh-Markup erkannt wird.

Da das loading-Attribut des <img>-Elements in allen gängigen Browsern unterstützt wird, ist es nicht erforderlich, JavaScript zum Lazy-Laden von Bildern zu verwenden. Wenn einer Seite zusätzliches JavaScript hinzugefügt wird, um Funktionen bereitzustellen, die der Browser bereits bietet, wirkt sich dies auf andere Aspekte der Seitenleistung aus, z. B. auf die INP.

Demo für Lazy Loading von Bildern

<iframe>-Elemente per Lazy Loading laden

Wenn Sie <iframe>-Elemente erst dann per Lazy Loading laden, wenn sie im Viewport sichtbar sind, können Sie erheblich Daten sparen und das Laden kritischer Ressourcen verbessern, die für das Laden der obersten Seite erforderlich sind. Da <iframe>-Elemente im Grunde genommen ganze HTML-Dokumente sind, die in einem übergeordneten Dokument geladen werden, können sie eine erhebliche Anzahl von Unterressourcen enthalten, insbesondere JavaScript. Dies kann sich erheblich auf die INP einer Seite auswirken, wenn die Aufgaben innerhalb dieser Frames viel Verarbeitungszeit erfordern.

Einbettungen von Drittanbietern sind ein häufiger Anwendungsfall für <iframe>-Elemente. Beispielsweise werden für eingebettete Videoplayer oder Social-Media-Beiträge häufig <iframe>-Elemente verwendet. Diese erfordern oft eine erhebliche Anzahl von Unterressourcen, was auch zu Bandbreitenkonflikten für die Ressourcen der übergeordneten Seite führen kann. So können Sie beim Lazy-Loading eines eingebetteten YouTube-Videos beim ersten Laden der Seite mehr als 500 KiB sparen. Beim Lazy-Loading des Facebook-Plug-ins für die „Mag ich“-Schaltfläche werden mehr als 200 KiB eingespart, davon hauptsächlich JavaScript.

In jedem Fall sollten Sie Lazy Loading für <iframe>-Elemente verwenden, die sich auf einer Seite „below the fold“ befinden, wenn es nicht unbedingt erforderlich ist, sie vorab zu laden. Dies kann die Nutzerfreundlichkeit erheblich verbessern.

Das loading-Attribut für <iframe>-Elemente

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

  • "eager" ist der Standardwert. Er informiert den Browser, das HTML des <iframe>-Elements und seine Unterressourcen sofort zu laden.
  • "lazy" verzögert das Laden des HTML-Codes und der untergeordneten Ressourcen des <iframe>-Elements, bis es sich in einem vordefinierten Abstand zum Darstellungsbereich befindet.

Demo für Lazy Loading von iFrames

Fassaden

Anstatt ein eingebettetes Element sofort beim Laden der Seite zu laden, kannst du es auf Anfrage als Reaktion auf eine Nutzerinteraktion laden. Dazu können Sie ein Bild oder ein anderes geeignetes HTML-Element anzeigen, bis der Nutzer damit interagiert. Sobald der Nutzer mit dem Element interagiert, kannst du es durch das eingebettete Element des Drittanbieters ersetzen. Diese Technik wird als Fassade bezeichnet.

Ein häufiger Anwendungsfall für Fassaden sind Video-Embeddings von Drittanbieterdiensten, bei denen neben den Videoinhalten möglicherweise viele zusätzliche und potenziell teure Unterressourcen wie JavaScript geladen werden. In einem solchen Fall muss der Nutzer vor der Wiedergabe mit eingebetteten Videos interagieren, indem er auf die Wiedergabeschaltfläche klickt, es sei denn, es gibt einen triftigen Grund für die automatische Wiedergabe.

Das ist eine gute Gelegenheit, ein statisches Bild zu zeigen, das optisch dem eingebetteten Video ähnelt, und dabei erheblich Bandbreite zu sparen. Sobald der Nutzer auf das Bild klickt, wird es durch das tatsächliche <iframe>-Embed ersetzt. Dadurch wird der Download der HTML-Datei und der Unterressourcen des Drittanbieter-<iframe>-Elements ausgelöst.

Neben der Verbesserung des ersten Seitenladevorgangs ist ein weiterer wichtiger Vorteil, dass die für die Bereitstellung des Videos erforderlichen Ressourcen nicht heruntergeladen werden, wenn der Nutzer das Video nie abspielt. Dies ist ein gutes Muster, da der Nutzer nur das herunterlädt, was er tatsächlich möchte, ohne möglicherweise falsche Annahmen über die Anforderungen des Nutzers zu treffen.

Chat-Widgets sind ein weiterer hervorragender Anwendungsfall für die Fassade. Die meisten Chat-Widgets laden erhebliche Mengen an JavaScript herunter, was sich negativ auf das Laden der Seite und die Reaktionsfähigkeit auf Nutzereingaben auswirken kann. Wie bei allen anderen Elementen, die vorab geladen werden, fallen die Kosten beim Laden an. Im Fall eines Chat-Widgets beabsichtigt jedoch nicht jeder Nutzer, damit zu interagieren.

Bei einer Fassade hingegen ist es möglich, die Schaltfläche „Starten Sie den Chat“ des Drittanbieters durch eine gefälschte Schaltfläche zu ersetzen. Sobald der Nutzer mit dem Widget interagiert, z. B. den Mauszeiger eine angemessene Zeit lang darauf bewegt oder darauf klickt, wird das tatsächliche, funktionsfähige Chat-Widget eingeblendet, wenn der Nutzer es benötigt.

Es ist zwar möglich, eigene Fassade zu erstellen, aber es gibt auch Open-Source-Optionen für beliebte Drittanbieter, z. B. lite-youtube-embed für YouTube-Videos, lite-vimeo-embed für Vimeo-Videos und React Live Chat Loader für Chat-Widgets.

JavaScript-Bibliotheken für Lazy Loading

Wenn Sie <video>-Elemente, <video>-Element-poster-Bilder, Bilder, die über die CSS-Property background-image geladen werden, oder andere nicht unterstützte Elemente mit Lazy Loading laden möchten, können Sie eine JavaScript-basierte Lazy-Loading-Lösung wie lazysizes oder yall.js verwenden, da das Lazy Loading dieser Arten von Ressourcen keine Funktion auf Browserebene ist.

Insbesondere das automatische Abspielen und Loopen von <video>-Elementen ohne Audiotrack ist eine viel effizientere Alternative als die Verwendung von animierten GIFs, die oft um ein Vielfaches größer sein können als eine Videoressource mit vergleichbarer visueller Qualität. Trotzdem können diese Videos in Bezug auf die Bandbreite eine große Rolle spielen. Das Lazy-Loading ist daher eine zusätzliche Optimierung, mit der sich die verschwendeten Bandbreiten erheblich reduzieren lassen.

Die meisten dieser Bibliotheken verwenden die Intersection Observer API und zusätzlich die Mutation Observer API, wenn sich die HTML-Seite nach dem ersten 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, aber Sie möchten es mit einer JavaScript-Lösung lazy laden. Mit yall.js ist das 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 werden mit yall.js alle infrage kommenden HTML-Elemente mit der Klasse "lazy" beobachtet. Nachdem yall.js auf der Seite geladen und ausgeführt wurde, wird das Video erst geladen, wenn der Nutzer es in den Darstellungsbereich scrollt. In diesem Fall werden die data-src-Attribute der untergeordneten <source>-Elemente des <video>-Elements durch src-Attribute ersetzt. Dadurch wird eine Anfrage zum Herunterladen des Videos gesendet und die Wiedergabe beginnt automatisch.

Wissen testen

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

"eager"
Richtig!
"lazy"
Bitte versuchen Sie es noch einmal.

Wann sind JavaScript-basierte Lösungen für Lazy Loading sinnvoll?

Für alle Ressourcen, die mit Lazy Loading geladen werden können.
Bitte versuchen Sie es noch einmal.
Für Ressourcen, bei denen das loading-Attribut nicht unterstützt wird, z. B. bei automatisch wiedergegebenen Videos, die animierte Bilder ersetzen sollen, oder beim Lazy-Load des Posterbilds eines <video>-Elements.
Richtig!

Wann ist eine Fassade ein nützliches Verfahren?

Für alle eingebetteten Inhalte von Drittanbietern, die viel Daten verbrauchen, unabhängig von den Anforderungen der Nutzer.
Bitte versuchen Sie es noch einmal.
Für alle eingebetteten Inhalte von Drittanbietern, bei denen die zum Laden erforderlichen Ressourcen nicht nur umfangreich sind, sondern bei denen es eine hohe Wahrscheinlichkeit gibt, dass nicht alle Nutzer mit ihnen interagieren können.
Richtig!

Als Nächstes: Prefetching und Pre-Rendering

Da Sie jetzt mit dem Lazy-Loading von Bildern und <iframe>-Elementen vertraut sind, können Sie dafür sorgen, dass Seiten schneller geladen werden, ohne die Anforderungen Ihrer Nutzer zu vernachlässigen. Es gibt jedoch Fälle, in denen das spekulative Laden von Ressourcen wünschenswert sein kann. Im nächsten Modul erfahren Sie mehr über das Vorabladen und Vorabrendering und wie diese Techniken bei sorgfältiger Anwendung die Navigation zu nachfolgenden Seiten erheblich beschleunigen können, indem sie vorab geladen werden.