Lazy Loading - Bilder nachladen lassen

Lazy Loading - Bilder nachladen lassen

 

Bilder nachladen um die initiale Ladezeit zu verkürzen

 

Fast jeder Entwickler oder Webseiten-Betreiber hat bereits von einem Lazy Loading gelesen oder aus Webentwickler-Kreisen gehört.

Es gibt viele Arten des Lazy-Loadings, wie zum Beispiel das Nachladen von JavaScript in WordPress. Es können auch Schriftarten, Icons oder andere Ressourcen auf der Webseite nachgeladen werden, um die Seite schneller aufrufbar zu machen. Das macht vor allem für mobile Besucher deiner Webseite Sinn, die mit einer niedrigeren Bandbreite surfen. Natürlich können Bilder erst nach einer kurzen Zeit angesehen werden, aber zumindest können die Texte schon einmal gelesen werden. Das wird vor allem von Google belohnt und der Besucher wird deine Seite seltener direkt wieder verlassen.

Ich möchte mich in diesem Beitrag um das Nachladen von Bildern beschäftigen.

Vielleicht hast du das Lazy Loading bereits auf der Startseite von Codepalm oder in der Beitrags-Übersicht gesehen. Bilder erscheinen erst nach einer sehr kurzen Zeit mit einem "Fading"-Effekt. Sollte das Bild bereits im Cache des Browsers liegen, wird der Fading-Effekt immer noch ausgeführt, jedoch erscheinen die Bilder wesentlich schneller.

Lass uns direkt in die Integration des Skripts einsteigen, damit auch deine Webseite einen Boost erhält.

 

Ein Hinweis vorweg: Das Lazy-Loading Script funktioniert nur für Benutzer, die JavaScript aktiviert haben. Sollte ein Benutzer einen Browser mit deaktiverten JavaScript verwenden, werden die Bilder gar nicht mehr ausgeliefert. Da die meisten Webseiten aber JavaScript dringend benötigen, empfehle ich dir einen Hinweis für Benutzer ausgeben zu lassen, der erklärt, dass es aktiviert werden muss, um das beste Benutzererlebnis für die Webseite zu garantieren. Mittlerweile ist die Verwendung von JavaScript so weit verbreitet, dass es nur noch einen verschwindend geringen Teil von Benutzern gibt, die JavaScript deaktivert haben.

 

Vorbereitung des JavaScripts

 

Die Vorlage des Skripts habe ich von Dean Hume, einen englisch-sprachigen Programmierer, der unter anderem an der Frostbite-Engine bei EA arbeitet. Er ist ein sehr passionierter Entwickler und hat bereits ein paar Lektüren über das Web geschrieben. Das Lazy Loading Script von Dean Hume ist eher Kleinteilig beschrieben. Auf seiner Webseite erhältst du weitere Informationen zum Skript.

Zusammengefasst sieht das Skript so aus:

const images = document.querySelectorAll( '.lazy-load' );
const config = {
	rootMargin: '50px 0px',
	threshold: 0.01
};

let imageCount = images.length;
let observer;

if( !( 'IntersectionObserver' in window ) ) {
  loadImagesImmediately( images );
}
else {
	observer = new IntersectionObserver( onIntersection, config );
	for (let i = 0; i < images.length; i++) { 
		let image = images[i];
		if( image.classList.contains( 'js-lazy-image--handled' ) )
			continue;
		observer.observe( image );
	}
}

function fetchImage( url ) {
	return new Promise((resolve, reject) => {
		const image = new Image();
		image.src = url;
		image.onload = resolve;
		image.onerror = reject;
	});
}

function preloadImage( image ) {
	const src = image.dataset.src;
	if( !src )
		return;
	return fetchImage( src ).then(() => { applyImage( image, src ); });
}

function loadImagesImmediately( images ) {
	for( let i=0; i < images.length; i++ ) { 
		let image = images[i];
		preloadImage( image );
	}
}

function disconnect() {
	if( !observer )
		return;
	observer.disconnect();
}

function onIntersection( entries ) {
	if( imageCount === 0 ) {
		disconnect();
		return;
	}
	
	for( let i=0; i < entries.length; i++ ) {
		let entry = entries[i];
		if( entry.intersectionRatio > 0 ) {
			imageCount--;
			observer.unobserve( entry.target );
			preloadImage( entry.target );
		}
	}
}

function applyImage( img, src ) {
	img.classList.add( 'js-lazy-image--handled' );
	img.src = src;
	img.classList.add( 'fade-in' );
}
 

Dieses JavaScript kannst du kopieren und in deine Webseite einfügen. Im besten Fall erstellst du dir eine eigene JS-Datei und fügst es in jeder Einzelseite deiner Webseite ein. Die Implementierung funktioniert am besten über einen globalen Header oder Footer.

Ein Hinweis zur Webseite von Dean Hume oder diesem Beitrag wäre nett, ist aber nicht notwendig.

 

Nachzuladende Bilder platzieren

 

Durch das JavaScript erhält man die Möglichkeit Bilder nachzuladen. Nun müssen wir den einzelnen Bildern noch beibringen, dass sie nachgeladen werden sollen. Das geschieht durch die Angabe der Klasse "lazy-load" im <img>-Tag.

Ein kleines Problemchen, das ich beim Script von Dean Hume entdeckt habe, ist das fehlende "src"-Attribut. Da der Wert aus dem "data-src"-Attribut in die "src" geladen wird, sobald der Besucher das Bild in den sichtbaren Bereich verschiebt, wird das Bild kurzzeitig als "fehlend" markiert. Um dieses Problem zu vermeiden, habe ich ein 1x1 Pixel großes, transparentes PNG-Bild in das Base64-Format gebracht. Diese Ressource kann in das "src"-Attribut hinzugefügt werden, damit das Bild nicht als "Broken Image" dargestellt wird.

Das ist der Code, um ein transparentes Pixel als src zu platzieren, ohne das Bild irgendwo auf dem Server gesichert zu haben:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABBJREFUeNpi+P//PwNAgAEACPwC/tuiTRYAAAAASUVORK5CYII=
 

In einem anderen Beitrag zeige ich, wie du Broken Image Elemente grafisch verbesserst. Das wäre eine Alternative zur Verwendung des transparenten Base64-Pixels.

 

Das <img>-Tag wird nun leider etwas umfangreicher in unserem HTML-Code. Aber solange du beim Rendering und dem ersten Aufruf der Webseite Zeit sparst, solltest du dieses kleine Übel in Kauf nehmen. Solltest du PHP für deine Webseite verwenden, kannst du das Base64-Bild in einer globalen Variable sichern und es in jedem src-Attribut des Bilds ausgeben lassen. Das empfehle ich den fortgeschritteneren Entwicklern ;)

Das fertige <img>-Tag kannst du dir gerne kopieren und durch alle Bilder auf deiner Webseite ersetzen. Stelle sicher, dass du den Wert des Attributs "data-src" mit dem entsprechenden Ressourcen-Pfad änderst.

<img class="lazy-load" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABBJREFUeNpi+P//PwNAgAEACPwC/tuiTRYAAAAASUVORK5CYII=" data-src="/pfad/zum/bild.jpg" />
 

Wenn du ein wenig Know-How mit JavaScript besitzt, kannst du das Skript auch relativ erweitern, um ein ganzes "srcset" eines Bilds zu erstellen, um verschiedenartige Darstellungsgrößen des Browsers mit unterschiedlich großen Bildern abzudecken. Die einfachste Methode das zu erreichen, ist die Bearbeitung der vorletzten Zeile des JavaScript-Codes. Das img.src muss nur zu einem img.srcset geändert werden. Beachte aber, dass du damit dann jedes Bild mit einem srcset-Attribut versiehst. Die Ausgabe der "src" wird dann eliminiert. Zudem musst du darauf achten, dass das Base64-Bild in das Attribut srcset im <img>-Tag eingefügt wird, nicht mehr in das src-Attribut.

 

Kleine Randnotiz: Obwohl Google Pagespeed Insights die Bilder nicht in der Vorschau anzeigt, werden sie dennoch in der Google Bildersuche indexiert! Zum Glück ist Google mittlerweile Intelligent genug, um JavaScript zu verwenden :)

 

Bilder erscheinen lassen

 

Eine weitere kleine Erweiterung, die ich am JavaScript vorgenommen habe, ist ein "Fade In"-Effekt. Ich möchte ungern, dass Bilder abrupt auf meiner Seite erscheinen. Durch eine kleine CSS-Erweiterung kann das Bild mit einem Fading eingeblendet werden. Die Klasse wird automatisch durch das JavaScript gesetzt, sobald ein Bild geladen und in das src-Attribut gesetzt wird.

.fade-in {
	animation-name: fadeIn;
	animation-duration: 1.3s;
	animation-timing-function: cubic-bezier(0, 0, 0.4, 1);
	animation-fill-mode: forwards;
}
 

Dieses CSS-Snippet kannst du in eine geeignete CSS-Datei einfügen, die auf jeder Seite eingebunden wird. Natürlich kannst du ein wenig mit den Werten spielen, zum Beispiel um eine schnellere Fertigstellung der Animation zu erhalten, indem du die "animation-duration" verringerst.

Wenn du dich gut mit CSS auskennst, kannst du auch deine eigenen Einblend-Animationen erstellen.

 

Kleiner Tipp von mir: Bevor du das Skript einbindest und die Bilder austauschst, solltest du einen Performance-Test an deiner Seite durchführen. Das kannst du entweder mit Google Pagespeed Insights machen, oder mit meinen Lieblings-Alternativen, Yellowlab Tools und GTmetrix. Sichere deine Ergebnisse und führe die Änderungen an deiner Webseite durch. Starte danach eine erneute Analyse und vergleiche die Resultate (Denke an den Server-Cache, falls du einen verwendest).

Ich wusste, dass sich die Ladezeit durch das Skript verbessert, war aber hinterher sehr positiv überrascht, wie gut das Lazy-Loading tatsächlich ist. Nachdem das Skript implementiert war, habe ich einige Millisekunden Ladezeit gespart! Die Verbesserungen sind natürlich von Webseite zu Webseite verschieden. Das liegt einerseits an der Größe der verwendeten Bildern und andererseits an der Masse der Bilder auf einer Einzelseite.

Teile gerne deine Resultate in den Kommentaren mit mir. Ich bin gespannt, ob du auch so gute Verbesserungen feststellen kannst wie andere.

 

Codepalm
Lazy Loading - Bilder nachladen lassen
 

Das konnte dich auch interessieren

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

 

Kommentare

Sei der Erste, der einen Kommentar erstellt!

 
Secured By miniOrange