Die Hauptursache für Leistungsprobleme bei Webanwendungen und die Notwendigkeit von Lazy Loading

In modernen Webanwendungen sind Bilder ein zentrales Element, das die Benutzererfahrung (UX) und die Webleistung bestimmt. Mit der Zunahme der Nutzung hochauflösender Bilder und der zunehmenden Bedeutung von Bildinhalten auf der Seite ist eine Verlangsamung der Ladegeschwindigkeit von Websites ein unvermeidbares Problem geworden. Das gleichzeitige Laden aller Bilder zum Zeitpunkt der anfänglichen Ladephase führt zu einem schwerwiegenden Leistungsengpass.

  • Erhöhte Ladezeit (Verzögerung von FCP, LCP): Durch das Herunterladen von Bildern außerhalb des Viewports wird der Zeitpunkt, an dem ein Benutzer tatsächlich Inhalte sehen kann (First Contentful Paint), und der Zeitpunkt, an dem das größte Inhaltselement geladen wird (Largest Contentful Paint) erheblich verzögert. Dies hat auch negative Auswirkungen auf die Core Web Vitals.

  • Unnötiger Bandbreitenverbrauch: Auch Bilder, die der Benutzer nicht sieht, verbrauchen Netzwerkressourcen, was zu höheren Datentarifen in mobilen Umgebungen führt und in Desktop-Umgebungen andere wichtige Ressourcenläufe behindert.

  • Erhöhte Serverlast: Anfragen für alle Bilder erfolgen gleichzeitig, was zu einer Überlastung des Servers führt und die Stabilität des Dienstes beeinträchtigt.

Einer der effektivsten Strategien zur Lösung dieser Probleme ist Bilder Lazy Loading. Lazy Loading ist eine Technik, die es ermöglicht, anstatt alle Bilder zum Zeitpunkt des anfänglichen Ladevorgangs zu laden, Bilder asynchron zu laden, wenn sie in den Viewport des Benutzers eintreten oder einen bestimmten Schwellenwert erreichen.

Funktionsweise und Anwendungsweise von Lazy Loading für Bilder

Es gibt hauptsächlich zwei Hauptmethoden, um Lazy Loading anzuwenden, und es ist wichtig, die Vor- und Nachteile zu verstehen und je nach den Anforderungen Ihres Projekts auszuwählen.

1. Native Lazy Loading des Browsers (loading="lazy")

Dies ist die einfachste und wirksamste Methode, die durch das Hinzufügen des Attributs loading="lazy" zum HTML <img> Tag implementiert werden kann. Es wird von den meisten modernen Browsern unterstützt und die Browser selbst optimieren die Verwendung von Lazy Loading.

<img src="placeholder.jpg"
     data-src="actual-image.jpg"
     alt="Beschreibung des Bildes"
     loading="lazy"
     width="500"
     height="300">
  • Vorteile:

    • Einfachheit der Implementierung: Es ist möglich, dies nur durch das Hinzufügen eines HTML-Attributs ohne zusätzlichen JavaScript-Code anzuwenden.

    • Leistungsoptimierung: Da es auf Engine-Ebene im Browser implementiert ist, kann es effizienter und schneller als JavaScript-basierte Lösungen arbeiten.

    • Verringerung der Belastung für Entwickler: Der Browser kümmert sich um die Implementierung, ohne dass komplexe Intersection Observer-APIs oder Ereignis-Listener-Management erforderlich sind.

  • Nachteile:

    • Unterstützung durch Browser: Es wird möglicherweise nicht in allen älteren Browsern perfekt unterstützt (aber die meisten modernen Browser unterstützen es).

    • Mangelnde feine Kontrolle: Entwickler haben Schwierigkeiten, Schwellenwerte oder Ladestrategien genau zu steuern.

Empfehlung: Wenn keine speziellen Kontrollanforderungen bestehen, ist es ratsam, Native Lazy Loading vorrangig anzuwenden.

2. JavaScript-basiertes Lazy Loading (Nutzung der Intersection Observer API)

Wenn eine detailliertere Kontrolle erforderlich ist oder ein Fallback für Browser erforderlich ist, die das Attribut loading="lazy" nicht unterstützen, kann JavaScript-basiertes Lazy Loading implementiert werden. Früher wurde meist die Verwendung von Scroll-Ereignis-Listenern bevorzugt, aber aufgrund von Leistungsproblemen hat sich die Nutzung der Intersection Observer API als Standard etabliert.

Grundlegende Implementierungslogik:

  1. Anfänglich wird ein Placeholder-Bild im src-Attribut des Bildes oder die URL des tatsächlichen Bildes im data-src-Attribut angegeben.

  2. Eine Intersection Observer-Instanz wird erstellt, um die Bildelemente zu beobachten.

  3. Wenn das Bildelement in den Viewport eintritt oder die definierte Schwelle erreicht wird, wird die Callback-Funktion des Observers aufgerufen.

  4. Innerhalb der Callback-Funktion wird die tatsächliche Bild-URL, die im data-src gespeichert ist, in das src-Attribut verschoben, um das Bild zu laden.

  5. Nach Abschluss des Bildladens wird die Beobachtung des betreffenden Bildelements eingestellt (unobserve).

// HTML (Beispiel)
// <img class="lazyload" data-src="actual-image.jpg" alt="Beschreibung">

// JavaScript
document.addEventListener("DOMContentLoaded", function() {
    const lazyImages = [].slice.call(document.querySelectorAll("img.lazyload"));

    if ("IntersectionObserver" in window) {
        let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    let lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    // lazyImage.srcset = lazyImage.dataset.srcset; // Wenn srcset benötigt wird
                    lazyImage.classList.remove("lazyload");
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        }, {
            // Root Margin: Der Bereich, in dem Bilder vorab vom Rand des Viewports geladen werden (px oder %)
            rootMargin: "0px 0px 200px 0px"
        });

        lazyImages.forEach(function(lazyImage) {
            lazyImageObserver.observe(lazyImage);
        });
    } else {
        // Fallback für Browser, die IntersectionObserver nicht unterstützen
        // (z. B. Verwendung von Scroll-Ereignisans Listenern oder sofortiges Laden aller Bilder)
        // Dieser Teil wird aus Leistungsgründen nicht empfohlen.
        lazyImages.forEach(function(lazyImage) {
            lazyImage.src = lazyImage.dataset.src;
        });
    }
});
  • Beliebte JavaScript-Lazy-Loading-Bibliotheken:

    • lazysizes: Sehr leichtgewichtig, SEO-freundlich und unterstützt eine Vielzahl von Bildformaten, einschließlich srcset und picture Elementen. Kann auch als Fallback für Native Lazy Loading verwendet werden.

    • lozad.js: Bietet eine kleine Bündelgröße und hohe Leistung.

Überlegungen und Optimierungstipps beim Implementieren von Lazy Loading

Lazy Loading ist eine leistungsstarke Technik zur Optimierung, aber eine unüberlegte Anwendung auf alle Bilder kann die Benutzererfahrung beeinträchtigen.

  1. Verwaltung von 'Above the Fold'-Bildern: Bei Bildern, die sofort im anfänglichen Viewport sichtbar sind ('Above the Fold'), sollte kein Lazy Loading angewendet werden. Diese Bilder beeinflussen die Largest Contentful Paint (LCP) der Seite direkt, weshalb sie mit loading="eager" gekennzeichnet oder von Lazy Loading ausgeschlossen werden sollten, um sofort geladen zu werden.
<img src="logo.png" alt="Unternehmenslogo" width="100" height="50" loading="eager">

LCP breakdown analysis

  1. Angabe von width und height-Attributen: Das width und height-Attribut sollte in HTML angegeben werden, um Layout-Shift (Cumulative Layout Shift, CLS) zu verhindern. Indem die Browser vorab Platz für das Bild reserviert, wird vermieden, dass es während des Ladens zu Verschiebungen im Layout kommt, was für eine Verbesserung der Core Web Vitals-Werte entscheidend ist.

  2. Verwendung von Placeholder-Bildern: Um visuelle Lücken für den Benutzer zu reduzieren, solange das Lazy Loading-Bild nicht geladen ist, ist es ratsam, verschwommenes, niedrig auflösendes Bild oder einen einfarbigen Hintergrund-Placeholder zu verwenden. Dies zeigt dem Benutzer, dass die Seite geladen wird.

  3. Nutzung von srcset und <picture>-Tags: Verwenden Sie responsive Bilder (srcset) und Art Direction (picture-Tags) in Kombination mit Lazy Loading, um Bilder zu liefern, die für verschiedene Bildschirmgrößen und -auflösungen optimiert sind, und um unnötige Bilddownloads weiter zu reduzieren.

<picture>
    <source srcset="image-large.webp" type="image/webp" media="(min-width: 1200px)" loading="lazy">
    <source srcset="image-medium.webp" type="image/webp" media="(min-width: 768px)" loading="lazy">
    <img src="placeholder.jpg" data-src="image-small.jpg" alt="Beschreibung" loading="lazy">
</picture>

Lighthouse performance score

Fazit: Lazy Loading als Schlüssel zur Optimierung der Leistung und Benutzererfahrung

Das Lazy Loading von Bildern verbessert nicht nur die Bildladezeiten, sondern ist auch eine unverzichtbare Optimierungstechnik für Webseiten, die die anfängliche Ladeleistung der Seite revolutioniert, den Bandbreitenverbrauch effizient gestaltet und die Serverlast verringert. Angesichts der zunehmenden Bedeutung von Webleistungskennzahlen wie Core Web Vitals ist die strategische Anwendung von Lazy Loading ein wesentlicher Aspekt, den Entwickler bei ihrer Arbeit berücksichtigen müssen.

Priorisieren Sie die native Lazy Loading-Methode, aber betrachten Sie die Implementierung mit JavaScript oder den Einsatz von Bibliotheken, wenn eine detaillierte Steuerung erforderlich ist oder bestimmte Browserumgebungen unterstützt werden müssen. Zudem sollten Sie Optimierungstipps wie die Verwaltung von 'Above the Fold'-Bildern, das Spezifizieren von width/height und die Verwendung von Placeholders anwenden, um den Benutzern eine schnelle und angenehme Web-Erfahrung zu bieten.