Lazy Loading für Bilder

Bilder können auf einer Webseite erscheinen, weil sie im HTML-Code als <img>-Elemente oder CSS-Hintergrundbilder inline sind. In diesem Beitrag erfahren Sie, wie Sie beide Bildtypen per Lazy Loading laden.

Inline-Bilder

Die häufigsten Kandidaten für Lazy Loading sind Bilder, die in <img>-Elementen verwendet werden. Bei Inline-Bildern gibt es drei Optionen für Lazy Loading, die für eine optimale Kompatibilität mit verschiedenen Browsern kombiniert werden können:

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. Der Wert lazy weist den Browser an, das Bild sofort zu laden, wenn es sich im Darstellungsbereich befindet, und andere Bilder abzurufen, wenn der Nutzer in der Nähe scrollt.

Ausführliche Informationen zur Browserunterstützung finden Sie im Feld loading der MDN-Tabelle zur Browserkompatibilität. Wenn der Browser Lazy Loading nicht unterstützt, wird das Attribut ignoriert und Bilder werden wie gewohnt sofort geladen.

Bei den meisten Websites steigert das Hinzufügen dieses Attributs zu Inline-Bildern die Leistung und erspart 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 ohne Unterstützung von Lazy Loading von Vorteilen profitieren, müssen Sie dies mit einer der im Folgenden beschriebenen Methoden kombinieren.

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

Intersection Observer verwenden

Für das Lazy Loading von <img>-Elementen wird mithilfe von JavaScript überprüft, ob sie sich im Darstellungsbereich befinden. Ist dies der Fall, werden die Attribute src (und manchmal auch srcset) mit URLs zu den gewünschten Bildinhalten gefüllt.

Wenn Sie bereits Lazy Loading-Code geschrieben haben, haben Sie Ihre Aufgabe möglicherweise mithilfe von Event-Handlern wie scroll oder resize abgeschlossen. Dieser Ansatz ist zwar am besten mit allen Browsern kompatibel, moderne Browser bieten jedoch eine leistungsfähigere und effizientere Möglichkeit, die Sichtbarkeit von Elementen mithilfe der Intersection Observer API zu prüfen.

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, anstatt lästigen Code zur Erkennung der Elementsichtbarkeit zu schreiben. Jetzt müssen Sie nur noch entscheiden, was geschehen soll, wenn ein Element sichtbar ist. Nehmen wir dieses grundlegende Markup-Muster für deine verzögert 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 angezeigt wird, wenn die Seite zum ersten Mal geladen wird.
  3. Die Attribute data-src und data-srcset sind Platzhalterattribute, die die URL für das Bild enthalten, das Sie laden, sobald sich das Element im Darstellungsbereich befindet.

Sehen wir uns nun an, wie Intersection Observer in JavaScript verwendet wird, 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
  }
});

Im DOMContentLoaded-Ereignis des Dokuments fragt dieses Skript das DOM für alle <img>-Elemente mit der Klasse 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 daher als Polyfill für loading="lazy" verwendest, ist für die meisten Besucher Lazy Loading verfügbar.

Bilder in CSS

<img>-Tags sind die gängigste Art der Verwendung von Bildern auf Webseiten. Bilder können aber auch über die CSS-Property background-image und andere Attribute aufgerufen werden. Lazy Loading auf Browserebene gilt nicht für CSS-Hintergrundbilder. Wenn Sie Hintergrundbilder zum Lazy Loading verwenden möchten, müssen Sie daher andere Methoden in Betracht ziehen.

Im Gegensatz zu <img>-Elementen, die unabhängig von ihrer Sichtbarkeit geladen werden, erfolgt das Laden von Bildern in CSS mit mehr Spekulationen. Wenn die Dokument- und CSS-Objektmodelle und 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 mit einer externen Ressource nicht auf das aktuell erstellte Dokument zutrifft, fordert der Browser sie nicht an.

Dieses spekulative Verhalten kann verwendet werden, um das Laden von Bildern in CSS zu verzögern. Dazu wird mithilfe von JavaScript ermittelt, wann sich ein Element im Darstellungsbereich befindet, und anschließend eine Klasse auf dieses Element angewendet, die Stile zum Aufrufen eines Hintergrundbilds anwendet. Dadurch wird das Image zum Zeitpunkt der Anforderung und nicht zum anfänglichen Ladevorgang heruntergeladen. Nehmen wir als Beispiel ein Element mit einem großen Hero-Hintergrundbild:

<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 einem CSS-Code aufgerufen wird. In diesem Beispiel für Lazy Loading können Sie das Attribut background-image des div.lazy-background-Elements über eine visible-Klasse isolieren, die dem Element im Darstellungsbereich hinzugefügt wird:

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

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

Von hier aus kannst du mit JavaScript prüfen, ob sich das Element im Darstellungsbereich befindet (mit Intersection Observer!). Füge dann die visible-Klasse dem 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 insgesamt als auch die Netzwerkkonflikte während des Starts reduziert, indem das Laden der Bilder auf den Zeitpunkt verschoben wird, an dem sie tatsächlich benötigt werden. Dies kann die Startzeit verbessern und die Verarbeitung im Hauptthread reduzieren, da die Zeit für die Bilddecodierung reduziert wird.

Das Lazy Loading ist jedoch eine Technik, die sich negativ auf den Largest Contentful Paint-LCP Ihrer Website auswirken kann, wenn Sie die Methode zu sehr interessiert. Sie sollten vermeiden, Lazy Loading für Bilder zu verwenden, die sich beim Start im Darstellungsbereich befinden.

Wenn Sie JavaScript-basierte Lazy Loader verwenden, sollten Sie Lazy Loading für Bilder im Darstellungsbereich vermeiden, da bei diesen Lösungen häufig ein data-src- oder data-srcset-Attribut als Platzhalter für die Attribute src und srcset verwendet wird. Das Problem ist hier, dass sich das Laden dieser Bilder verzögert, da der Scanner zum Vorabladen des Browsers sie beim Start nicht finden kann.

Selbst wenn Sie Lazy Loading auf Browserebene für das Lazy Loading von Bildern im Darstellungsbereich verwenden, kann dies nach hinten ausgelöst werden. Wenn loading="lazy" auf ein Bild im Darstellungsbereich angewendet wird, wird dieses Bild verzögert angezeigt, bis der Browser sicher ist, dass es sich im Darstellungsbereich befindet. Dies kann sich auf den LCP einer Seite auswirken.

Bilder, die beim Start im Darstellungsbereich sichtbar sind, sollte nie per Lazy Loading geladen werden. Dieses Muster wirkt sich negativ auf den LCP und damit die Nutzererfahrung auf Ihrer Website aus. Wenn Sie ein Image beim Start benötigen, laden Sie es so schnell wie möglich, indem Sie kein Lazy Loading verwenden.

Lazy Loading von Bibliotheken

Nach Möglichkeit sollten Sie Lazy Loading auf Browserebene verwenden. Wenn dies jedoch nicht möglich ist, weil z. B. eine beträchtliche Gruppe von Nutzern immer noch ältere Browser nutzt, können Sie die folgenden Bibliotheken zum Lazy Loading von Bildern verwenden:

  • lazysizes ist eine Lazy-Loading-Bibliothek mit vollem Funktionsumfang, mit der Bilder und iFrames per Lazy Loading geladen werden. Das verwendete Muster ist dem hier gezeigten Codebeispiel insofern sehr ähnlich, als es automatisch an eine lazyload-Klasse für <img>-Elemente gebunden wird. Außerdem müssen Sie Bild-URLs in den Attributen data-src und/oder data-srcset angeben, deren Inhalte in die Attribute src und/oder srcset umgewandelt werden. Dabei wird Intersection Observer verwendet, den Sie mit Polyfills darstellen können. Außerdem kann es mit verschiedenen Plug-ins erweitert werden, um z. B. Lazy Loading für Videos zu nutzen. Weitere Informationen zur Verwendung von Lazysize
  • Vanilla-Lazyload ist eine einfache Option für Lazy Loading für Bilder, Hintergrundbilder, Videos, iFrames und Skripts. Sie nutzt Intersection Observer, unterstützt responsive Bilder und ermöglicht Lazy Loading auf Browserebene.
  • lozad.js ist eine weitere einfache Option, die nur Intersection Observer verwendet. Es ist also sehr leistungsfähig, muss aber mit Polyfill nachgerüstet werden, bevor du es in älteren Browsern verwenden kannst.
  • Wenn Sie eine React-spezifische Lazy Loading-Bibliothek benötigen, sollten Sie react-lazyload verwenden. Intersection Observer wird zwar nicht verwendet, liefert aber eine vertraute Methode zum Lazy Loading von Bildern für diejenigen, die mit der Entwicklung von Anwendungen mit React vertraut sind.