Lazy Loading für Bilder: 5 Methoden für schnellere Websites

Lazy Loading für Bilder: 5 Methoden für schnellere Websites

Bilder gehören zu den häufigsten Inhalten im Web, und genau deshalb wird die Ladezeit einer Seite schnell zum Problem.

Selbst gut optimierte Bilder bringen einiges an Gewicht auf die Waage. Das verlängert die Wartezeit, bevor Besucher an den Inhalt deiner Website kommen. Die Wahrscheinlichkeit ist hoch, dass sie ungeduldig werden und weiterziehen – es sei denn, du findest eine Art, Bilder zu laden, die das Tempogefühl nicht stört.

In diesem Artikel lernst du fünf Ansätze für das Lazy Loading von Bildern kennen, die du in deinen Werkzeugkasten für Web-Optimierung aufnehmen kannst, um die Nutzererfahrung auf deiner Website zu verbessern.

Was ist Lazy Loading?

Lazy Loading heißt, Bilder asynchron zu laden: erst nachdem der übrige Inhalt vollständig geladen ist, oder sogar an eine Bedingung geknüpft, nämlich sobald sie im Fenster des Browsers auftauchen. Scrollt jemand nicht bis ans Ende der Seite, werden die Bilder dort unten also gar nicht erst geladen.

Etliche Websites arbeiten so, besonders auffällig ist es bei bildlastigen Seiten. Stöbere einmal in deinem Lieblingsrevier für hochauflösende Fotos, und du merkst schnell, dass die Seite nur eine begrenzte Anzahl Bilder lädt. Beim Scrollen füllen sich die Platzhalter zügig mit den echten Bildern für die Vorschau. Achte zum Beispiel auf das Ladeverhalten von Unsplash.com: Sobald du diesen Teil der Seite ins Bild scrollst, wird der Platzhalter durch das Foto in voller Auflösung ersetzt.

Warum solltest du dich für Lazy Loading interessieren?

Es gibt mindestens zwei sehr gute Gründe, Bilder auf deiner Website per Lazy Loading nachzuladen:

  • Wenn deine Website JavaScript nutzt, um Inhalte anzuzeigen oder Funktionen bereitzustellen, wird das Laden des DOM schnell kritisch. Skripte warten üblicherweise, bis das DOM vollständig geladen ist, bevor sie loslaufen. Auf einer Seite mit vielen Bildern kann Lazy Loading – also das asynchrone Laden der Bilder – darüber entscheiden, ob Nutzer bleiben oder deine Website verlassen.
  • Die meisten Lazy-Loading-Lösungen laden ein Bild erst, wenn der Nutzer bis zu der Stelle gescrollt hat, an der es im Viewport erscheinen würde. Kommt er nie dort an, wird das Bild nie geladen. Das spart erheblich Bandbreite, und dafür danken dir die meisten Nutzer – vor allem die mit Mobilgerät und langsamer Verbindung.

Lazy Loading tut der Performance einer Website also gut. Aber wie geht man es am besten an?

Die eine perfekte Methode gibt es nicht.

Wenn du JavaScript lebst und atmest, ist eine eigene Lazy-Loading-Lösung kein Problem. Nichts gibt dir mehr Kontrolle, als etwas selbst zu schreiben.

Du kannst aber auch das Netz nach brauchbaren Ansätzen durchsuchen und mit ihnen experimentieren. Genau das habe ich getan – und dabei diese fünf interessanten Techniken gefunden.

#1 Natives Lazy Loading

Natives Lazy Loading für Bilder und iframes ist eine feine Sache. Einfacher als das folgende Markup geht es nicht:

markup
<img src="myimage.jpg" loading="lazy" alt="..." />
<iframe src="content.html" loading="lazy"></iframe>

Wie du siehst: kein JavaScript, kein dynamisches Austauschen von src bei Bildern und iframes, nur gutes altes HTML.

Das Attribut loading verzögert Bilder und iframes außerhalb des Sichtbereichs so lange, bis der Nutzer bis zu ihrer Position auf der Seite scrollt. loading kennt drei Werte:

  • lazy: genau das, was man für Lazy Loading braucht
  • eager: fordert den Browser auf, den angegebenen Inhalt sofort zu laden.
  • auto: überlässt dem Browser die Entscheidung über das Lazy Loading.

Diese Methode ist konkurrenzlos: kein Overhead, sauber und simpel. Zwar haben die großen Browser inzwischen eine gute Unterstützung für das Attribut loading, aber noch sind nicht alle Browser mit an Bord.

#2 Lazy Loading mit der Intersection Observer API

Die Intersection Observer API ist eine moderne Schnittstelle, mit der du Bilder und andere Inhalte verzögert nachladen kannst.

So beschreibt MDN diese API:

Die Intersection Observer API bietet eine Möglichkeit, Änderungen an der Überschneidung eines Zielelements mit einem Vorfahrenelement oder mit dem Viewport eines Dokuments auf oberster Ebene asynchron zu beobachten.

Anders gesagt: Asynchron beobachtet wird die Überschneidung eines Elements mit einem anderen.

Angenommen, du willst eine Bildergalerie per Lazy Loading laden. Das Markup jedes Bildes sähe dann so aus:

markup
<img data-src="image.jpg" alt="test image">

Der Pfad zum Bild steckt im Attribut data-src und nicht im Attribut src. Der Grund: Mit src würde das Bild sofort geladen, und genau das willst du nicht.

Im CSS gibst du jedem Bild eine min-height, sagen wir 100px. Damit bekommt jeder Bildplatz (das img-Element ohne src-Attribut) eine vertikale Ausdehnung:

css
img {
min-height: 100px;
/* weitere Styles hier */
}

Im JavaScript legst du anschließend ein Objekt config an und übergibst es an eine Instanz von intersectionObserver:

javascript
// ein Konfigurationsobjekt erstellen: rootMargin und threshold
// sind zwei Eigenschaften, die die Schnittstelle bereitstellt
const config = {
  rootMargin: '0px 0px 50px 0px',
  threshold: 0
};

// das Objekt config bei einer Instanz
// von intersectionObserver registrieren
let observer = new intersectionObserver(function(entries, self) {
// über jeden Eintrag iterieren
  entries.forEach(entry {
    // nur die Bilder verarbeiten, die sich überschneiden.
    // isIntersecting ist eine Eigenschaft der Schnittstelle
if(entry.isIntersecting) {
    /. / Fonction personnalisée qui copie le chemin vers l'image
      // von data-src nach src
preloadImage(entry.target);
      // das Bild sitzt jetzt, Beobachtung beenden
      self.unobserve(entry.target);
}
});
}, config);

Zum Schluss iterierst du über alle Bilder und meldest sie bei dieser iterationObserver-Instanz an:

javascript
const imgs = document.querySelectorAll('[data-src]');
imgs.forEach(img {
  observer.observe(img);
});

Die Vorteile dieser Lösung: Sie ist leicht umzusetzen, sie ist wirksam, und die schwere Rechenarbeit überlässt sie intersectionObserver.

Auf der anderen Seite unterstützen zwar die meisten Browser in ihren aktuellen Versionen die Intersection Observer API, sie wird aber nicht von allen Browsern durchgängig unterstützt. Zum Glück steht ein Polyfill bereit.

#3 Lozad.js – Lazy Loading mit JS

Schnell und bequem geht Lazy Loading auch, indem du eine JS-Bibliothek die Arbeit machen lässt.

Lozad ist ein sehr performanter, leichtgewichtiger und konfigurierbarer Lazy Loader in reinem JavaScript, ganz ohne Abhängigkeiten. Damit lädst du Bilder, Videos, iframes und einiges mehr verzögert nach, unter der Haube arbeitet die Intersection Observer API.

Lozad installierst du mit npm oder Yarn und importierst es über den Module Bundler deiner Wahl:

bash
npm install --save lozad

yarn add lozad
javascript
import lozad from 'lozad';

Du kannst die Bibliothek auch über ein CDN laden und sie in einem < script> ans Ende der HTML-Seite setzen:

markup
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>

Für eine einfache Umsetzung gibst du dem Asset im Markup dann die Klasse lozad:

markup
<img class="lozad" data-src="img.jpg">

Zum Schluss instanziierst du Lozad in deinem JS-Dokument:

javascript
const observer = lozad();
observer.observe();

Alle Details zur Nutzung der Bibliothek findest du im GitHub-Repository von Lozad.

Wenn du dich nicht in die Feinheiten der Intersection Observer API einarbeiten willst oder einfach eine schnelle Umsetzung für unterschiedliche Inhaltstypen suchst, ist Lozad eine ausgezeichnete Wahl.

Behalte nur die Browserunterstützung im Blick und kombiniere die Bibliothek gegebenenfalls mit einem Polyfill für die Intersection Observer API.

#4 Lazy Loading mit Unschärfe-Effekt

Zuerst siehst du eine unscharfe Kopie des Bildes in niedriger Auflösung, während die hochauflösende Fassung verzögert nachgeladen wird:

Unscharfes Platzhalterbild auf der Website Medium
Unscharfes Platzhalterbild auf der Website Medium
Hochauflösendes Bild mit Lazy Loading auf der Website Medium.
Hochauflösendes Bild, per Lazy Loading geladen, auf der Website Medium.

Diesen hübschen Unschärfe-Effekt kannst du auf mehreren Wegen umsetzen.

Die Vorteile dieser Lösung:

  • Performance: nur 463 Byte CSS und 1.007 Byte minifiziertes JavaScript.
  • Unterstützung für Retina-Displays
  • Ohne Abhängigkeiten: kein jQuery, keine weiteren Bibliotheken oder Frameworks nötig.
  • Progressive Enhancement für ältere Browser und für den Fall, dass JavaScript ausfällt.

Für einen solchen Effekt kannst du progressive-image.js herunterladen.

#5 Yall.js – Lazy Loading mit JS

Yall ist ein funktionsreiches Lazy-Loading-Skript für Bilder, Videos und iframes. Es setzt auf die Intersection Observer API und greift bei Bedarf geschickt auf klassische Event-Techniken zurück.

Wenn du Yall in dein Dokument einbindest, initialisierst du es so:

javascript
<script src="yall.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", yall);
</script>

Um dann ein einfaches img verzögert zu laden, brauchst du im Markup nur das hier:

markup
<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">

Achte dabei auf Folgendes:

  • Du gibst dem Element die Klasse lazy
  • Der Wert von src ist ein Platzhalterbild
  • Der Pfad zum eigentlichen Bild steht im Attribut data-src

Zu den Vorteilen von Yall gehören:

  • hohe Performance dank der Intersection Observer API
  • hervorragende Browserunterstützung (zurück bis IE11)
  • keine weiteren Abhängigkeiten nötig

Mehr zu den Möglichkeiten von Yall und zu komplexeren Umsetzungen findest du auf GitHub.

Fazit

Das war’s: fünf Methoden für das Lazy Loading von Bildern, die du ab sofort in deinen Projekten ausprobieren und testen kannst.

CSSHTML

Damien Flandrin Webentwickler seit 2010, Gründer von Gekkode und Email Impact. Jeder Artikel wird vor der Veröffentlichung an einem echten Projekt getestet. Kontakt
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.