Lazy Loading Gravatars in WordPress

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die meisten WordPress-Themes zeigen Benutzer- Gravatare in den Kommentar-Threads an. Es ist eine Möglichkeit, ein Bild mit dem Benutzer anzuzeigen, das mit der verwendeten E-Mail-Adresse verknüpft ist. Es ist eine nette Geste und heutzutage fast ein erwartetes Designmuster.

Jedes einzelne dieser Gravatare ist jedoch eine einzelne HTTP-Anfrage, wie jedes andere Bild auch. Ein Kommentar-Thread mit 50 Kommentaren bedeutet 50 HTTP-Anfragen, und das sind nicht immer besonders kleine Dateien. Igitt.

Lassen Sie sie Lazy Loaden.

Das Konzept

Lazy Loading ist die Idee, dass man das Bild gar nicht erst anfordert (keine HTTP-Anfrage), es sei denn, das Bild ist sichtbar. Das bedeutet, dass wir durch JavaScript festgestellt haben, dass das Bild sichtbar ist.

Lazy Loading bedeutet, dass die beiden Bilder, die sich außerhalb des Browserfensters befinden, nicht geladen werden, bis sie innerhalb des Browserfensters erscheinen.

Um diese HTTP-Anfragen für noch nicht gesehene Bilder zu stoppen, müssen wir direkt am Markup ansetzen. Wenn sich ein <img src=""> im HTML befindet, gibt es im Grunde keine Möglichkeit, den Browser davon abzuhalten, dieses Bild so schnell wie möglich herunterzuladen, egal ob es sichtbar ist oder nicht. Wir müssen also das src entfernen und es wieder einfügen, wenn wir bereit sind.

Moment mal

Es lohnt sich, hier innezuhalten, denn wir haben uns in zwielichtige Gefilde begeben.

Indem wir das src dieser Bilder entfernen und es nur mit JavaScript wieder einfügen, haben wir uns entschieden, dass wir bereit sind, leicht ungültiges HTML auszuliefern und uns zu 100 % auf ein Skript zu verlassen, das heruntergeladen und ausgeführt wird, damit diese Bilder überhaupt sichtbar werden.

Damit bin ich einverstanden. Vor allem, weil Gravatare ohnehin nur eine Verbesserung darstellen. Es ist keine große Sache, wenn sie nie angezeigt werden. Ich bin kein Hardliner bei den meisten JavaScript-Debatten, aber dies scheint ein besonders klarer Fall zu sein, in dem wir uns ohne Bedenken auf JavaScript verlassen können.

Ändern des HTML

Das ist die Änderung, die wir vornehmen würden

<!-- Normal image. No beating the browser preloader. -->
<img src="https://gravatar.whatever..." alt="" />

<!-- Let's change to this, which won't download anything. -->
<img data-src="https://gravatar.whatever..." alt="" />

Obwohl ein fehlendes src im <img> technisch ungültiges HTML ist. Es ist höchstwahrscheinlich unwichtig, da es die Funktionsweise von nichts beeinträchtigt. Wenn das ungültige HTML stört, könnten Sie immer einen extrem minimalistischen, leeren GIF-Daten-URL einfügen, wie zum Beispiel:

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" ... />

Die Verwendung von width und height Attributen ist wahrscheinlich ebenfalls eine gute Idee, um das Layout beizubehalten und Reflows zu vermeiden, wenn und wann die Bilder geladen werden.

Ändern des HTML... in WordPress

Aber wie ändert man das HTML, das WordPress als Teil eines Kommentar-Threads ausgibt? Kommentare sind in WordPress etwas ungewöhnlich, da WordPress Core Ihnen das HTML liefert, es ist nicht Teil Ihres Themes wie die meisten anderen HTMLs.

Wahrscheinlich sehen Sie in Ihrer Datei `comments.php` diese Funktion

<?php wp_list_comments(); ?>

Welche einen Haufen <li>s mit Ihrem gesamten Kommentar-Thread ausgibt. Dort gibt es nicht viele Möglichkeiten, die Ausgabe von Bildern zu manipulieren. Außer, wir können es! Wir können dort eine Callback-Funktion angeben

<?php wp_list_comments('callback=csstricks_comment'); ?>

Dieser Callback ist der Name einer Funktion, die wir in unsere `functions.php`-Datei einfügen können. Hier ist ein Beispiel für diese Funktion, die ein <li> zurückgeben muss

function csstricks_comment($comment, $args, $depth) {

  $GLOBALS['comment'] = $comment; ?>

  <li <?php comment_class(); ?>">

     <img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="50" height="50" class="lazyload-gravatar" alt="User Avatar" data-src="<?php echo get_avatar_url(get_comment_author_email($comment_ID), array("size" => 160)); ?>">

     <?php comment_text(); ?>

  <?php # phantom </li> ?>

<?php }

Das ist sehr vereinfacht, aber Sie sehen, was wir getan haben. Wir haben das src durch das leere GIF ersetzt, wir haben einen class-Namen hinzugefügt, den wir schließlich in JavaScript für das Lazy Loading verwenden werden, wir haben ein data-src für das eigentliche Gravatar hinzugefügt und wir verwenden width und height Attribute für Platzhalter. Hier ist mein tatsächlicher vollständiger Callback, der aktuell auf CSS-Tricks live ist.

Wenn wir dies jetzt ohne jegliche JavaScript-Arbeit ausliefern würden, hätten wir immer noch einen perfekt funktionierenden Kommentar-Thread, nur mit Bildern, die nie laden.

Jetzt sind wir bereit für Lazy Loading

Der schwierige Teil ist vorbei. Wir sind jetzt perfekt für Lazy Loading vorbereitet. Wenn wir ein Skript schreiben würden, wäre es so

  1. Den sichtbaren Bereich des Browserfensters ermitteln
  2. Die Position auf der Seite für jedes Bild mit der Klasse .lazyload-gravatar ermitteln
  3. Wenn eines dieser Bilder im sichtbaren Bereich liegt, den src-Wert durch den Wert von data-src ersetzen
  4. Wenn sich der sichtbare Bereich des Browserfensters auf irgendeine Weise ändert, das obige neu auswerten

Wir könnten uns daran machen, das selbst zu schreiben. Und wir könnten es schaffen! Aber, und ich bin sicher, das überrascht Sie nicht, es ist ein bisschen knifflig und nuanciert. Browserübergreifende Bedenken, Performance-Bedenken, funktioniert-das-auf-dem-Handy-Bedenken, um nur einige zu nennen. Das ist die Art von Ding, für die ich gerne auf die Arbeit anderer zurückgreife, anstatt sie selbst zu machen.

Auch hier keine Überraschung, es gibt jede Menge Optionen zur Auswahl. In meinem Fall verwende ich auf CSS-Tricks gerne jQuery und habe mich für eine jQuery-basierte Lösung entschieden, die für mich ziemlich gut aussah.

Die API ist denkbar einfach. Nachdem ich die Bibliothek mit den anderen verwendeten Bibliotheken gebündelt habe, rufe ich einfach auf

$('.lazyload-gravatar').Lazy();

Sehen Sie, wie gut das funktioniert!

Das sind eine ganze Menge gesparter HTTP-Anfragen und eine Menge gut für die Performance.

Man wünscht sich, dass sich Webstandards und Browser darauf einigen und es zu einer nativen Funktion machen.