Lazy Loading für Bilder

Bilder können auf einer Webseite angezeigt werden, weil sie im HTML-Code als <img>-Elemente oder als CSS-Hintergrundbilder enthalten sind. In diesem Beitrag erfährst du, wie du beide Arten von Bildern per Lazy Loading laden kannst.

Inline-Bilder

Die häufigsten Lazy Loading-Möglichkeiten sind Bilder, die in <img>-Elementen verwendet werden. Bei Inline-Bildern gibt es drei Optionen für Lazy Loading, die kombiniert werden können, um die Browserkompatibilität zu optimieren:

Lazy Loading auf Browserebene verwenden

Sowohl Chrome als auch Firefox unterstützen Lazy Loading mit dem Attribut loading. Dieses Attribut kann <img>- und <iframe>-Elementen hinzugefügt werden. Mit dem Wert lazy wird der Browser angewiesen, das Bild sofort zu laden, wenn es sich im Darstellungsbereich befindet, und andere Bilder abzurufen, wenn der Nutzer in die Nähe scrollt.

Im Feld loading der Browserkompatibilitätstabelle von MDN finden Sie Details zur Browserunterstützung. Wenn der Browser Lazy Loading nicht unterstützt, wird das Attribut ignoriert und Bilder werden wie gewohnt sofort geladen.

Bei den meisten Websites führt das Hinzufügen dieses Attributs zu Inline-Bildern zu einer Leistungssteigerung und erspart den Nutzern das Laden von Bildern, zu denen sie möglicherweise nie scrollen. Wenn Sie eine große Anzahl von Bildern haben und sicherstellen möchten, dass Nutzer von Browsern die Vorteile von Lazy Loading nicht unterstützen, müssen Sie dies mit einer der nachfolgend beschriebenen Methoden kombinieren.

Weitere Informationen finden Sie unter Lazy Loading für das Web auf Browserebene.

Intersection Observer verwenden

Zum Polyfill-Lazy Loading von <img>-Elementen verwenden wir JavaScript, um zu prüfen, ob sie sich im Darstellungsbereich befinden. Ist dies der Fall, werden die src-Attribute (und manchmal srcset) mit den URLs zu den gewünschten Bildinhalten gefüllt.

Wenn Sie bereits Code für Lazy Loading geschrieben haben, wurde Ihre Aufgabe möglicherweise mit Event-Handlern wie scroll oder resize ausgeführt. Dieser Ansatz ist zwar browserübergreifend am kompatibel, aber mit modernen Browsern lässt sich die Sichtbarkeit von Elementen über die Intersection Observer API noch leistungsstärker und effizienter erledigen.

Intersection Observer ist einfacher zu verwenden und zu lesen als Code, der auf verschiedenen Event-Handlern basiert, da Sie nur einen Beobachter registrieren müssen, um Elemente zu beobachten, und keinen mühsamen Code zur Erkennung der Elementsichtbarkeit schreiben. Jetzt müssen Sie nur noch entscheiden, wie vorgegangen werden soll, wenn ein Element sichtbar ist. Nehmen wir folgendes grundlegende Markup-Muster für die langsam geladenen <img>-Elemente an:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

Es gibt drei relevante Teile dieses Markups, auf die Sie sich konzentrieren sollten:

  1. Das Attribut class, mit dem Sie das Element in JavaScript auswählen.
  2. Das Attribut src, das auf ein Platzhalterbild verweist, das beim ersten Laden der Seite angezeigt wird
  3. Die Attribute data-src und data-srcset. Dabei handelt es sich um Platzhalterattribute, die die URL für das Bild enthalten, das geladen wird, sobald sich das Element im Darstellungsbereich befindet.

Sehen wir uns nun an, wie Sie Intersection Observer in JavaScript verwenden, um Bilder mithilfe dieses Markup-Musters per Lazy Loading zu laden:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  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;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

Beim DOMContentLoaded-Ereignis des Dokuments fragt dieses Skript das DOM für alle <img>-Elemente mit einer Klasse von lazy ab. Wenn Intersection Observer verfügbar ist, erstellen Sie einen neuen Beobachter, der einen Callback ausführt, wenn img.lazy-Elemente in den Darstellungsbereich gelangen.

Intersection Observer ist in allen modernen Browsern verfügbar. Wenn du es als Polyfill für loading="lazy" verwendest, ist Lazy Loading für die meisten Besucher verfügbar.

Bilder in CSS

Während <img>-Tags am häufigsten zur Verwendung von Bildern auf Webseiten verwendet werden, können Bilder auch über die CSS-Eigenschaft background-image und andere Eigenschaften aufgerufen werden. Lazy Loading auf Browserebene gilt nicht für CSS-Hintergrundbilder. Daher sollten Sie andere Methoden in Betracht ziehen, wenn Sie Hintergrundbilder für Lazy Loading haben.

Im Gegensatz zu <img>-Elementen, die unabhängig von ihrer Sichtbarkeit geladen werden, erfolgt das Laden von Bildern in CSS mit mehr Spekulation. Wenn die Dokument- und CSS-Objektmodelle sowie die Rendering-Struktur erstellt werden, prüft der Browser, wie CSS auf ein Dokument angewendet wird, bevor externe Ressourcen angefordert werden. Wenn der Browser festgestellt hat, dass eine CSS-Regel zu einer externen Ressource nicht auf das Dokument zutrifft, da es derzeit erstellt ist, fordert der Browser sie nicht an.

Dieses spekulative Verhalten kann verwendet werden, um das Laden von Bildern in CSS zu verzögern. Mithilfe von JavaScript wird festgestellt, wann sich ein Element im Darstellungsbereich befindet. Anschließend wird auf dieses Element eine Klasse angewendet, die einen Stil anwendet, der ein Hintergrundbild aufruft. Dadurch wird das Image bei Bedarf und nicht beim ersten Laden heruntergeladen. Nehmen wir z. B. ein Element, das ein großes Hero-Hintergrundbild enthält:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

Das div.lazy-background-Element enthält normalerweise das Hero-Hintergrundbild, das von CSS aufgerufen wird. In diesem Beispiel für Lazy Loading können Sie die Eigenschaft background-image des div.lazy-background-Elements jedoch über eine visible-Klasse isolieren, die dem Element hinzugefügt wird, wenn es sich im Darstellungsbereich befindet:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

Prüfen Sie hier mit JavaScript, ob sich das Element im Darstellungsbereich befindet (mit Intersection Observer!) und fügen Sie dann die visible-Klasse zum div.lazy-background-Element hinzu, das das Bild lädt:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

Auswirkungen auf Largest Contentful Paint (LCP)

Lazy Loading ist eine hervorragende Optimierung, die sowohl die Datennutzung als auch Netzwerkkonflikte während des Starts reduziert, indem das Laden von Bildern auf den tatsächlichen Zeitpunkt verschoben wird. Dies kann die Startzeit verbessern und die Verarbeitung im Hauptthread reduzieren, da weniger Zeit für die Bilddecodierung benötigt wird.

Lazy Loading ist jedoch eine Technik, die sich negativ auf den Largest Contentful Paint Ihrer Website auswirken kann, wenn Sie das Verfahren zu sehr begleitet haben. Sie sollten jedoch das Lazy Loading von Bildern, die sich beim Start im Darstellungsbereich befinden, vermeiden.

Bei Verwendung von JavaScript-basierten Lazy Loadings sollten Sie Lazy Loading von Bildern im Darstellungsbereich vermeiden, da diese Lösungen häufig ein data-src- oder data-srcset-Attribut als Platzhalter für src- und srcset-Attribute verwenden. Das Problem hier ist, dass das Laden dieser Bilder verzögert wird, da der Browser zum Vorabladen sie beim Start nicht finden kann.

Selbst die Verwendung von Lazy Loading zum Lazy Loading von Bildern auf Browserebene kann im Darstellungsbereich nach hinten losgehen. Wenn loading="lazy" auf ein Bild im Darstellungsbereich angewendet wird, wird dieses Bild verzögert, bis der Browser sicher ist, dass es sich im Darstellungsbereich befindet. Dies kann sich auf den LCP einer Seite auswirken.

Nie: Lazy Loading von Bildern, die beim Start im Darstellungsbereich sichtbar sind. Dieses Muster wirkt sich negativ auf den LCP-Wert deiner Website und damit auf die Nutzererfahrung aus. Wenn Sie ein Image beim Start benötigen, laden Sie es so schnell wie möglich, ohne Lazy Loading zu verwenden.

Lazy Loading von Bibliotheken

Sofern möglich, sollten Sie Lazy Loading auf Browserebene verwenden. Sollte dies jedoch nicht möglich sein, weil beispielsweise eine große Gruppe von Nutzern immer noch auf ältere Browser angewiesen ist, können Sie die folgenden Bibliotheken für das Lazy Loading von Bildern verwenden:

  • lazysizes ist eine voll funktionsfähige Lazy-Loading-Bibliothek, mit der Bilder und iFrames per Lazy Loading geladen werden. Das verwendete Muster ist den hier gezeigten Codebeispielen sehr ähnlich, da es automatisch an eine lazyload-Klasse für <img>-Elemente gebunden wird und Sie Bild-URLs in den Attributen data-src und/oder data-srcset angeben müssen, deren Inhalt in src- bzw. srcset-Attribute ausgetauscht wird. Dabei wird Intersection Observer verwendet, die Sie mit Polyfill verwenden können, und es kann mit einer Reihe von Plug-ins erweitert werden, um beispielsweise Lazy-Loading für Videos durchzuführen. Weitere Informationen zur Verwendung von Lazysizes
  • Vanilla-Lazyload ist eine einfache Option für Lazy Loading von Bildern, Hintergrundbildern, Videos, iFrames und Skripts. Es nutzt Intersection Observer, unterstützt responsive Bilder und ermöglicht Lazy Loading auf Browserebene.
  • lozad.js ist eine weitere schlanke Option, die nur Intersection Observer verwendet. Daher ist sie sehr leistungsstark, muss jedoch mit Polypen gefüllt werden, bevor Sie sie in älteren Browsern verwenden können.
  • Wenn Sie eine React-spezifische Lazy Loading-Bibliothek benötigen, ist react-lazyload eine gute Option. Intersection Observer kommt hier zwar nicht zum Einsatz, bietet aber eine bekannte Methode zum Lazy Loading von Bildern für diejenigen, die mit der Entwicklung von Anwendungen mit React vertraut sind.