Lazy-Loading ist eine beliebte Technik, um die gefühlte Geschwindigkeit einer Internetseite zu erhöhen. Statt alle Bilder einer Webseite schon beim Laden der Seite mitzuladen, werden nur die Bilder geladen, die auch tatsächlich sichtbar sind. Damit verringert man gerade auf langen Seiten die initial geladene Menge an Bildern.

Bisher hatte das mit etwas Aufwand zu tun, und auf jeden Fall mit JavaScript. Netterweise gibt es inzwischen eine deutlich einfachere Lösung.

Die bisherigen Lösungen gingen davon aus, dass irgendeine Form von LazyLoad-JavaScript auf der Seite montiert wurde, und das HTML eines jeden Bildes abgeändert werden musste:

<!-- Load when visible -->
<img src="example-lowres.jpg"
  data-src="example-highres.jpg" class="lazyload"
  alt="" width="240" height="240" />

Moderne Browser unterstützen aber auch ein Attribut namens loading, dass das Ladeverhalten von <img> und <iframe> steuert, ohne zusätzliches Javascript. Genaue Details kann man einem Blog-Post des Chrome-Entwicklers Addy Osmani über Lazy-Loading entnehmen, im HTML sieht das aber schlicht und ergreifend wie folgt aus:

<!-- Load when visible -->
<img src="example.jpg" loading="lazy" alt="" width="240" height="240" />
<iframe src="example.html" loading="lazy"></iframe>

<!-- Load as soon as possible -->
<img src="example.jpg" loading="eager" alt="" width="240" height="240" />
<iframe src="example.html" loading="eager"></iframe>

Danach sollte man beim Besuch einer Seite, die mit loading-Attributen versehen ist, beim Öffnen des Inspektors bemerken, dass erst beim Scrollen auf der Seite weiter unten befindliche Bilder bzw. iFrames nachgeladen werden – oder halt, wenn der Browser sich gerade langweilt.

Damit entfällt in Google Chrome, Mozilla Firefox, Opera und dem aktuellen Microsoft Edge die Notwendigkeit, JavaScript für Lazy-Loading auf der eigenen Seite zu montieren (so wie in allen Browsern, die zukünftig dieses Feature unterstützen). Zudem können Browser ohne diese Möglichkeit bzw. ohne JavaScript immer noch die selben Inhalte sehen.

Wichtig ist aber, nicht jedes Element mit Lazy-Loading auszustatten. Demnach scheint es für Browser Performance-Probleme für Bilder / iFrames im sichtbaren Bereich zu geben, wenn dort Lazy-Loading verwendet wird. Eine halbwegs smarte Lösung würde also zumindest die erste Ressource auf der Seite nicht mit Lazy-Loading ausstatten.

Mit der Gießkanne: Umsetzung in NodeJs

Um in einem gesamten Content-Block jedes <img> und <iframe> mit dem passenden loading-Attribut zu versehen, reicht folgende kleine Funktion:

const lazyloadAttributes = function(html, loading = 'lazy') {
  return html.replace(/(<(?:img|iframe) )/g, '$1loading="' + loading + '" ');
};

Um einen Automatismus für das Ignorieren der ersten X Bilder / iFrames für Lazy-Loading zu erreichen, führen wir den neuen Paramter ignoreLoadingFor ein, der standardmäßig für das erste passende Element keine Ersetzung vornimmt. Wenn wir ignoreLoadingFor auf 2 setzen, werden entsprechend die ersten zwei Elemente ignoriert. Mit etwas Geschick kann man so zum Beispiel auch in Schleifen nur das erste Element in dem ersten Schleifenelement nicht ersetzen.

const lazyloadAttributes = function(html, loading = 'lazy', ignoreLoadingFor = 1) {
  return html.replace(/(<(?:img|iframe) )/g, function(all) {
    if (ignoreLoadingFor > 0) {
      ignoreLoadingFor --;
      return all;
    }
    return all + 'loading="' + loading + '" ';
  });
};

Damit werden in einem Block die ersten X Elemente nicht mit Lazy-Loading versehen, alle nachfolgenden Elemente aber schon.

…und in PHP

Gleichsam können in PHP z.B. redaktionelle Texte durch diese Funktion durchgeleitet werden, um überall Lazy-Loading hinzuzufügen:

function lazyloadAttributes($html, $loading = 'lazy')
{
    return preg_replace('/(<(?:img|iframe) )/is', '$1loading="' . $loading . '" ', $html);
}

…und mit dem Mechanismus zum Ignorieren der ersten Bilder / iFrames für Lazy-Loading:

function lazyloadAttributes(string $html, string $loading = 'lazy', int $ignoreLoadingFor = 1): string
{
    $html = preg_replace('/(<(?:img|iframe) )/is', '$1loading="' . $loading . '" ', $html);
    if ($ignoreLoadingFor > 0) {
        $html = preg_replace('/(<(?:img|iframe)) loading=".+?"/is', '$1', $html, $ignoreLoadingFor);
    }
    return $html;
}

…wenn auch etwas weniger elegant als in JavaScript.

Fazit

Eigentlich gibt es wenig Gründe, dass Attribut nicht einzusetzen. Gerade auf länglichen Übersichtsseiten kann das Erlebnis für den Besucher deutlich verbessert werden. Und für Mobilgeräten mit geringer Bandbreite kann der Geschwindigkeitszuwachs immens sein.


Andere Artikel zum Thema · · · ·

Zuletzt geändert am

fboës - Der Blog