Sie haben vielleicht gehört (oder sogar den Ruf erlassen), dass „wir einfach Lazy Loading verwenden können!“, wenn wir nach einer Möglichkeit suchen, eine besonders schwere Webseite zu optimieren.
Lazy Loading ist eine gängige Technik, um Bilder schrittweise anzufordern, wenn sie in den sichtbaren Bereich gelangen, anstatt alle auf einmal nach dem Parsen des Seiten-HTMLs. Dies kann das anfängliche Seitenvolumen reduzieren und uns helfen, unsere Performance-Budgets einzuhalten, indem Bilder nur bei Bedarf angefordert werden.
Es kann effektiv sein. Aber es bringt auch einige Nachteile mit sich. Dazu kommen wir noch! Tatsächlich hat Rahul Nanwani eine ausführliche Abhandlung über mehrere Lazy-Loading-Methoden verfasst, die zeigt, wie komplex einige davon sind.
In diesem Beitrag werden wir eine Implementierung betrachten, die bereits in diesem Beitrag von Preethi kurz behandelt wurde. Wir werden diese erweitern, damit Sie Ihre eigene Lazy-Loading-Implementierung auf Ihrer Website hinzufügen können, so wie ich es auf dieser kleinen Demo-Website getan habe.
Wir werden auf folgenden Themen eingehen:
- Das HTML-Markup für Lazy Loading
- Erkennen, wann Bilder mit Intersection Observer geladen werden sollen
- Unterstützung für responsive Bilder mit
picture- undsource-Elementen hinzufügen - Einen attraktiven Anfangszustand mit kleinen Bildern und CSS erstellen
- Massenproduktion von Bildassets
- Helfer zur Generierung des benötigten HTMLs erstellen
Das werden wir bauen
Warum nicht natives Lazy Loading?
Derzeit ist Lazy Loading keine Funktion, die Browser nativ für uns übernehmen können. Obwohl sich dies in einigen Browsern bald ändern wird, mit der Einführung von Chrome 75, das Lazy Loading für Bilder und iframes unterstützen soll. Bis dahin (und auch danach, wenn wir uns gut mit anderen Browsern verstehen wollen – was wir sollten) wird Lazy Loading mithilfe von JavaScript implementiert. Es gibt eine Reihe von Bibliotheken und Frameworks, die dabei helfen.
Einige Static Site Generatoren, Bibliotheken und Frameworks enthalten Dienstprogramme, die diese Funktion "out of the box" bereitstellen, was sich als beliebt erweist, da viele nach integrierten Möglichkeiten suchen, diese Funktion in ihre Websites einzubauen. Ich habe jedoch auch einen Trend bemerkt, bei dem einige ganze Bibliotheken oder Frameworks übernehmen, nur um Zugang zu dieser Funktion zu erhalten. Als sparsamer, auf Performance und Inklusivität bedachter Spaßvogel bin ich dem gegenüber etwas skeptisch. Lassen Sie uns also betrachten, wie Sie dies selbst implementieren könnten, ohne auf ein bestimmtes Framework oder eine Bibliothek angewiesen zu sein.

Die typischen Abläufe für Lazy Loading
Die meisten Ansätze folgen einem Muster wie diesem:
Zuerst etwas HTML, um unsere Lazy-Loading-Bilder zu definieren.
<!--
Don't include a src attribute in images you wish to load lazily.
Instead specify their src safely in a data attribute
-->
<img data-src="lighthouse.jpg" alt="A snazzy lighthouse" class="lazy" />
Wann sollten Bilder geladen werden?
Als Nächstes verwenden wir eine Art JavaScript-Magie, um das src-Attribut korrekt zu setzen, wenn das Bild in den sichtbaren Bereich gelangt. Dies war einst eine aufwendige JavaScript-Operation, die das Lauschen auf Scroll- und Resize-Events des Fensters beinhaltete, aber IntersectionObserver hat Abhilfe geschaffen.
Ein Intersection Observer wird so erstellt:
// Set up an intersection observer with some options
var observer = new IntersectionObserver(lazyLoad, {
// where in relation to the edge of the viewport, we are observing
rootMargin: "100px",
// how much of the element needs to have intersected
// in order to fire our loading function
threshold: 1.0
});
Wir haben unseren neuen Observer angewiesen, eine Funktion namens lazyLoad aufzurufen, wenn die beobachteten Bedingungen erfüllt sind. Die Elemente, die diese Bedingungen erfüllen, werden an diese Funktion übergeben, damit wir sie manipulieren können... zum Beispiel, um sie tatsächlich zu laden und anzuzeigen.
function lazyLoad(elements) {
elements.forEach(image => {
if (image.intersectionRatio > 0) {
// set the src attribute to trigger a load
image.src = image.dataset.src;
// stop observing this element. Our work here is done!
observer.unobserve(item.target);
};
});
};
Gut. Unsere Bilder erhalten das korrekte src-Attribut zugewiesen, wenn sie in den sichtbaren Bereich gelangen, was sie lädt. Aber welche Bilder? Wir müssen der Intersection Observer API mitteilen, welche Elemente uns interessieren. Glücklicherweise haben wir jedem Element eine CSS-Klasse von .lazy zugewiesen, genau zu diesem Zweck.
// Tell our observer to observe all img elements with a "lazy" class
var lazyImages = document.querySelectorAll('img.lazy');
lazyImages.forEach(img => {
observer.observe(img);
});
Schön, aber perfekt?
Das scheint gut zu funktionieren, aber es gibt einige Nachteile zu beachten:
- Bis (oder es sei denn) JavaScript geladen wird und erfolgreich ausgeführt wird, haben wir eine Menge Bildelemente auf unserer Seite, die nicht funktionieren werden. Wir haben sie bewusst unbrauchbar gemacht, indem wir das
src-Attribut entfernt haben. Das ist das Ergebnis, das wir uns gewünscht haben, aber jetzt sind wir von JavaScript abhängig, damit diese Bilder geladen werden. Während es stimmt, dass JavaScript heutzutage im Web allgegenwärtig ist – das Web erreicht ein breites Spektrum an Geräten und Netzwerbedingungen –, kann JavaScript eine teure Ergänzung zu unseren Performance-Budgets werden, insbesondere wenn es an der Auslieferung und Darstellung von Inhalten beteiligt ist. Wie Jake Archibaldeinst bemerkte: alle Ihre Benutzer sind Nicht-JS, während sie Ihr JS herunterladen.
Anders ausgedrückt, dies ist nichts, was man leichtfertig nehmen sollte. - Selbst wenn dies erfolgreich funktioniert, haben wir leere Elemente auf unserer Seite, die beim Laden vielleicht einen kleinen visuellen Ruck auslösen. Vielleicht können wir das Bild zuerst andeuten und etwas Besonderes tun. Dazu kommen wir gleich.
Die geplante native Lazy-Loading-Implementierung von Chrome sollte bei unserem ersten Punkt helfen. Wenn dem Element ein loading-Attribut gegeben wurde, kann Chrome das src-Attribut zur richtigen Zeit berücksichtigen, anstatt es sofort anzufordern, sobald es im HTML erscheint.
Der Editor-Entwurf der Spezifikation enthält Unterstützung für verschiedene Ladeverhalten:
<img loading="lazy" />: Sagt dem Browser, dass dieses Bild bei Bedarf lazy geladen werden soll.<img loading="eager" />: Sagt dem Browser, dass dieses Bild sofort geladen werden soll.<img loading="auto" />: Lässt den Browser seine eigene Einschätzung vornehmen.
Browser ohne diese Unterstützung könnten das Bild dank der resilienten Natur von HTML und Browsern, die unbekannte HTML-Attribute ignorieren, normal laden.
Aber… schlagen Sie Alarm! Dieses Feature ist noch nicht in Chrome angekommen, und es gibt auch Unsicherheit, ob und wann andere Browser es implementieren werden. Wir können Feature Detection verwenden, um zu entscheiden, welche Methode wir verwenden, aber dies bietet immer noch keinen soliden Ansatz für progressive Verbesserung, bei dem die Bilder keine Abhängigkeit von JavaScript haben.
<img data-src="lighthouse.jpg" alt="A snazzy lighthouse" loading="lazy" class="lazy" />
// If the browser supports lazy loading, we can safely assign the src
// attributes without instantly triggering an eager image load.
if ("loading" in HTMLImageElement.prototype) {
const lazyImages = document.querySelectorAll("img.lazy");
lazyImages.forEach(img => {
img.src = img.dataset.src;
});
}
else {
// Use our own lazyLoading with Intersection Observers and all that jazz
}
Als Begleiter zu responsiven Bildern
Unter der Annahme, dass wir mit der Tatsache einverstanden sind, dass JavaScript vorerst eine Abhängigkeit darstellt, wenden wir uns einem verwandten Thema zu: responsive Bilder.
Wenn wir schon den Aufwand betreiben, Bilder erst bei Bedarf in den Browser zu liefern, scheint es fair, dass wir auch sicherstellen wollen, dass wir sie in der besten Größe liefern, je nachdem, wie sie angezeigt werden. Zum Beispiel gibt es keinen Grund, die 1200px breite Version eines Bildes herunterzuladen, wenn das Gerät, das es anzeigt, ihm nur eine Breite von 400px gibt. Optimieren wir!
HTML bietet uns einige Möglichkeiten, responsive Bilder zu implementieren, die unterschiedliche Bildquellen mit unterschiedlichen Viewport-Bedingungen verknüpfen. Ich verwende gerne das picture-Element, wie hier:
<picture>
<source srcset="massive-lighthouse.jpg" media="(min-width: 1200px)">
<source srcset="medium-lighthouse.jpg" media="(min-width: 700px)">
<source srcset="small-lighthouse.jpg" media="(min-width: 300px)">
<img src="regular-lighthouse.jpg" alt="snazzy lighthouse" />
</picture>
Sie werden bemerken, dass jedes source-Element ein srcset-Attribut hat, das eine Bild-URL angibt, und ein media-Attribut, das die Bedingungen definiert, unter denen diese Quelle verwendet werden soll. Der Browser wählt die am besten geeignete Quelle aus der Liste entsprechend den Medienbedingungen, wobei ein Standard-img-Element als Standard/Fallback dient.
Können wir diese beiden Ansätze kombinieren, um responsive Bilder mit Lazy Loading zu erstellen?
Natürlich können wir das! Machen wir es.
Anstatt ein leeres Bild zu haben, bis wir unser Lazy Loading durchführen, lade ich gerne ein Platzhalterbild mit winziger Dateigröße. Dies verursacht zwar den Overhead von mehr HTTP-Anfragen, gibt aber auch einen schönen Effekt, indem es das Bild andeutet, bevor es ankommt. Sie haben diesen Effekt vielleicht schon bei Medium gesehen oder als Ergebnis einer Seite, die das Lazy Loading von Gatsby verwendet.
Wir können dies erreichen, indem wir zunächst die Bildquellen in unserem picture-Element als winzige Versionen desselben Assets definieren und dann CSS verwenden, um sie auf die gleiche Größe wie ihre höher aufgelösten Geschwister zu skalieren. Dann können wir über unseren Intersection Observer jede der angegebenen Quellen aktualisieren, um auf die richtigen Bildquellen zu verweisen.
Anfangs könnte unser picture-Element also so aussehen:
<picture class="lazy">
<source srcset="tiny-lighthouse.jpg" media="(min-width: 1200px)">
<source srcset="tiny-lighthouse.jpg" media="(min-width: 700px)">
<source srcset="tiny-lighthouse.jpg" media="(min-width: 300px)">
<img src="tiny-lighthouse.jpg" alt="snazzy cake" />
</picture>
Unabhängig von der Viewport-Größe wird ein winziges 20px Bild angezeigt. Wir werden es im nächsten Schritt mit CSS aufblasen.
Vorschau des Bildes mit Stil
Der Browser kann das winzige Vorschau-Bild mit CSS hochskalieren, damit es in das gesamte picture-Element passt, anstatt nur auf 20px. Wie Sie sich vorstellen können, wird es bei der Hochskalierung eines niedrig aufgelösten Bildes auf größere Abmessungen etwas... pixelig.
picture {
width: 100%; /* stretch to fit its containing element */
overflow: hidden;
}
picture img {
width: 100%; /* stretch to fill the picture element */
}

Um die durch die Skalierung des Bildes entstehende Pixeligkeit zu mildern, können wir einen Weichzeichnerfilter verwenden.
picture.lazy img {
filter: blur(20px);
}

Quellen mit JavaScript wechseln
Mit einer kleinen Anpassung können wir die gleiche Technik wie zuvor verwenden, um die korrekten URLs für unsere srcset- und src-Attribute zu setzen.
function lazyLoad(elements) {
elements.forEach(picture => {
if (picture.intersectionRatio > 0) {
// gather all the image and source elements in this picture
var sources = picture.children;
for (var s = 0; s < sources.length; s++) {
var source = sources[s];
// set a new srcset on the source elements
if (sources.hasAttribute("srcset")) {
source.setAttribute("srcset", ONE_OF_OUR_BIGGER_IMAGES);
}
// or a new src on the img element
else {
source.setAttribute("src", ONE_OF_OUR_BIGGER_IMAGES);
}
}
// stop observing this element. Our work here is done!
observer.unobserve(item.target);
};
});
};
Ein letzter Schritt, um den Effekt zu vervollständigen: Entfernen Sie den Weichzeichner-Effekt aus dem Bild, sobald die neue Quelle geladen wurde. Ein JavaScript-Event-Listener, der auf das load-Ereignis jeder neuen Bildressource wartet, kann dies für uns erledigen.
// remove the lazy class when the full image is loaded to unblur
source.addEventListener('load', image => {
image.target.closest("picture").classList.remove("lazy")
}, false);
Mit einem Hauch von CSS können wir einen schönen Übergang erstellen, der den Weichzeichner sanft ausblendet.
picture img {
...
transition: filter 0.5s,
}
Ein kleiner Helfer von unseren Freunden
Großartig. Mit ein wenig JavaScript, ein paar Zeilen CSS und einer sehr überschaubaren Menge an HTML haben wir eine Lazy-Loading-Technik erstellt, die auch responsive Bilder berücksichtigt. Warum sind wir also nicht zufrieden?
Nun, wir haben zwei Reibungspunkte geschaffen:
- Unser Markup zum Hinzufügen von Bildern ist komplexer als zuvor. Das Leben war einfacher, als wir nur ein einziges
img-Tag mit einem guten altensrc-Attribut brauchten. - Wir müssen auch mehrere Versionen jedes Bildassets erstellen, um jede Viewport-Größe und den Preload-Status zu füllen. Das ist mehr Arbeit.
Keine Sorge. Wir können beides optimieren.
Generierung der HTML-Elemente
Betrachten wir zuerst die Generierung des HTMLs, anstatt es von Hand zu schreiben.
Welches Werkzeug Sie auch immer zur Generierung Ihres HTMLs verwenden, es bietet wahrscheinlich eine Funktion für Includes, Funktionen, Shortcodes oder Makros. Ich bin ein großer Fan von solchen Helfern. Sie halten komplexere oder nuancierte Codefragmente konsistent und sparen Zeit, indem sie das Schreiben von langem Code überflüssig machen. Die meisten Static Site Generatoren bieten diese Möglichkeit.
- Jekyll erlaubt Ihnen, benutzerdefinierte Plugins zu erstellen.
- Hugo bietet Ihnen benutzerdefinierte Shortcodes.
- Eleventy hat Shortcodes für alle von ihm unterstützten Template-Engines.
- Es gibt noch viele mehr...
Als Beispiel habe ich in meinem Beispielprojekt, das mit Eleventy erstellt wurde, einen Shortcode namens lazypicture erstellt. Der Shortcode wird wie folgt verwendet:
{% lazypicture lighthouse.jpg "A snazzy lighthouse" %}
Um das benötigte HTML zur Build-Zeit zu generieren.
<picture class="lazy">
<source srcset="/images/tiny/lighthouse.jpg" media="(min-width: 1200px)">
<source srcset="/images/tiny/lighthouse.jpg" media="(min-width: 700px)">
<source srcset="/images/tiny/lighthouse.jpg" media="(min-width: 300px)">
<img src="/images/tiny/lighthouse.jpg" alt="A snazzy lighthouse" />
</picture>
Generierung der Bild-Assets
Der andere Aufwand, den wir uns selbst gemacht haben, ist die Generierung von Bild-Assets in verschiedenen Größen. Wir wollen nicht manuell jede Größe jedes Bildes erstellen und optimieren. Diese Aufgabe schreit nach Automatisierung.
Die Art und Weise, wie Sie dies automatisieren, sollte die Anzahl der benötigten Bild-Assets und die Häufigkeit, mit der Sie weitere Bilder hinzufügen, berücksichtigen. Sie könnten die Bilder als Teil jedes Builds generieren. Oder Sie könnten einige Bildtransformation-Services bei jeder Anfrage nutzen. Lassen Sie uns beide Optionen kurz betrachten.
Option 1: Bilder während Ihres Builds generieren
Beliebte Werkzeuge existieren dafür. Ob Sie Ihre Builds mit Grunt, Gulp, webpack, Make oder etwas anderem ausführen, es gibt wahrscheinlich ein Werkzeug für Sie.
Das folgende Beispiel verwendet gulp-image-resize in einer Gulp-Aufgabe als Teil eines Gulp-Build-Prozesses. Es kann ein Verzeichnis voller Bild-Assets verarbeiten und die benötigten Varianten generieren. Es bietet eine Vielzahl von Optionen zur Steuerung, und Sie können es mit anderen Gulp-Utilities kombinieren, um beispielsweise die verschiedenen Varianten gemäß Ihren Konventionen zu benennen.
var gulp = require('gulp');
var imageResize = require('gulp-image-resize');
gulp.task('default', function () {
gulp.src('src/**/*.{jpg,png}')
.pipe(imageResize({
width: 100,
height: 100
}))
.pipe(gulp.dest('dist'));
});
Die CSS-Tricks-Website verwendet einen ähnlichen Ansatz (dank der Funktion für benutzerdefinierte Größen in WordPress), um alle ihre verschiedenen Bildgrößen automatisch zu generieren. (Oh ja! CSS-Tricks lebt seine Philosophie!) ResponsiveBreakpoints.com bietet eine Web-UI, um mit verschiedenen Einstellungen und Optionen zum Erstellen von Bildsets zu experimentieren und generiert sogar den Code für Sie.
Oder Sie können es programmatisch nutzen, wie Chris auf Twitter erwähnte.
Ich benutze das auf @CSS, aber programmatisch!
Jedes hochgeladene Bild wird hierdurchgelassen, um die perfekten Breakpoints zu finden, dann auf @cloudinary hochgeladen und von dort ausgeliefert (Originale auf unserem Server).https://#/Gt75vujTVL
— Chris Coyier (@chriscoyier) 10. Juni 2019
Wenn Sie jedoch so viele Bilddateien wie CSS-Tricks haben, kann die Durchführung dieser Arbeit als Teil eines Build-Schritts umständlich werden. Eine gute Caching-Strategie in Ihrem Build und andere Dateiverwaltungsaufgaben können helfen, aber es kann leicht zu einem langen Build-Prozess kommen, der Ihren Computer aufheizt, während er all die Arbeit verrichtet.
Eine Alternative ist, diese Ressourcen bei Bedarf zu transformieren, anstatt während eines Build-Schritts. Das ist die zweite Option.
Option 2: On-Demand-Bildtransformationen
Ich bin ein starker Befürworter der Vorab-Rendering von Inhalten. Ich habe diesen Ansatz (oft als JAMstack bezeichnet) schon seit einiger Zeit propagiert und glaube, dass er zahlreiche Vorteile in Bezug auf Performance, Sicherheit und Einfachheit bietet. (Chris fasste dies schön in einem Beitrag über Static Hosting und JAMstack zusammen.)
Dennoch mag die Idee, verschiedene Bildgrößen bei jeder Anfrage zu generieren, meinen Lazy-Loading-Zielen widersprechen. Tatsächlich gibt es heute eine Reihe von Diensten und Unternehmen, die sich darauf spezialisiert haben, und sie tun dies auf sehr leistungsfähige und bequeme Weise.
Die Kombination von Bildtransformationen mit leistungsfähigen CDN- und Asset-Caching-Funktionen von Unternehmen wie Netlify, Fastly und Cloudinary kann Bilder mit den von Ihnen über eine URL angegebenen Dimensionen schnell generieren. Jeder Dienst verfügt über erhebliche Verarbeitungsleistung, um diese Transformationen im laufenden Betrieb durchzuführen und die generierten Bilder für die zukünftige Verwendung zu cachen. Dies ermöglicht eine nahtlose Darstellung für nachfolgende Anfragen.
Da ich bei Netlify arbeite, werde ich dies anhand eines Beispiels mit dem Dienst von Netlify erläutern. Aber die anderen, die ich erwähnt habe, funktionieren auf ähnliche Weise.
Der Image Transformation Service von Netlify baut auf etwas auf, das Netlify Large Media genannt wird. Dies ist eine Funktion, die dazu dient, große Assets in Ihrer Versionskontrolle zu verwalten. Git ist standardmäßig nicht gut darin, aber Git Large File Storage kann Git erweitern, um die Einbeziehung großer Assets in Ihre Repositories zu ermöglichen, ohne sie zu überladen und unhandlich zu machen.
Sie können mehr über den Hintergrund dieses Ansatzes zur Verwaltung großer Assets lesen, wenn Sie interessiert sind.
Die Einbeziehung von Bildern unter Versionskontrolle in unsere Git-Repositories ist ein zusätzlicher Vorteil, aber für unsere Zwecke sind wir mehr daran interessiert, die Vorteile der On-the-Fly-Transformationen dieser Bilder zu nutzen.
Netlify sucht nach querystring-Parametern, wenn Bilder transformiert werden. Sie können die Höhe, Breite und die Art des Zuschnitts angeben, die Sie durchführen möchten. Wie hier:
- Ein Rohbild ohne Transformationen
/images/apple3.jpg - Ein Bild, das auf 300px Breite skaliert wurde
/images/apple3.jpg?nf_resize=fit&w=300 - Ein Bild, das als 500px mal 500px zugeschnitten wurde, mit automatischer Fokuspunkterkennung
/images/apple3.jpg?nf_resize= smartcrop&w=500&h=500
Da wir wissen, dass wir jede Bildgröße aus einer einzigen Quellbilddatei in unserer Versionskontrolle erstellen und liefern können, muss der JavaScript-Code, den wir zum Aktualisieren der Bildquellen verwenden, nur die von uns gewählten Größenparameter enthalten.
Der Ansatz kann Ihre Website-Build-Prozesse drastisch beschleunigen, da die Arbeit nun ausgelagert und nicht mehr zur Build-Zeit ausgeführt wird.
Zusammenfassung
Wir haben hier viel Stoff behandelt. Es gibt viele gut erreichbare Optionen zur Implementierung von responsiven Bildern mit Lazy Loading. Hoffentlich gibt Ihnen dies genügend Informationen, um zweimal nachzudenken, bevor Sie zum nächstbesten Framework greifen, um Zugang zu dieser Art von Funktionalität zu erhalten.
Diese Demo-Website fasst eine Reihe dieser Konzepte zusammen und verwendet den Bildtransformationsservice von Netlify.
Noch einmal, um den Ablauf zusammenzufassen
- Ein Static Site Generator mit einem Shortcode erleichtert die Erstellung der
picture-Elemente. - Netlify Large Media hostet und transformiert die Bilder, liefert sie dann als winzige 20px breite Versionen aus, bevor die größeren Dateien bei Bedarf geladen werden.
- CSS skaliert die winzigen Bilder hoch und weicht sie aus, um die Vorschau-Platzhalterbilder zu erstellen.
- Die Intersection Observer API erkennt, wann die Bild-Assets durch die entsprechenden größeren Versionen ausgetauscht werden sollen.
- JavaScript erkennt das
load-Ereignis für die größeren Bilder und entfernt den Weichzeichner-Effekt, um das höher aufgelöste Rendering freizugeben.
Aus irgendeinem Grund fühlt sich Gulp im Jahr 2019 schmutzig an. ;)
Das 5. Bild (von Chris Meeds https://unsplash.com/photos/9FidI-IQxwY) lädt bei mir auf meinem Laptop nie. 1440×689
Phil, wenn die Viewport-Höhe kleiner ist als die Bildhöhe, lädt das vollständige Bild nicht richtig. Die Klasse
lazy-initialbleibt auf dem<picture>-Element. Stellen Sie Ihren Desktop-Bildschirm auf etwa 1440x810 ein, um zu sehen, was ich meine. Genauer gesagt, das Foto von Chris Meads in Ihrer Demo. Getestet mit Chrome 75, Firefox 67, Safari 12.1.Ich finde das tatsächlich sehr cool.
https://codepen.io/marvin52/post/hack-lazy-load
Benutzt JS, funktioniert aber zu 100% ohne. Kurz gesagt – fügen Sie ein (verstecktes) Bild als ersten Inhalt auf der Seite hinzu (oder zumindest vor anderen Bildern); da dieses Bild keinen src hat, wirft es einen Fehler; der Fehlercode tauscht den src aller anderen Bilder auf der Seite aus (oder Sie können gezielt Bilder mit einer bestimmten Klasse ansprechen); da der Fehler des ersten Bildes auftritt, bevor andere Bilder zu laden beginnen, laden diese erst, wenn später Ihr "Lazy"-Code ausgeführt wird. Wenn kein JS vorhanden ist, wird der onerror-Code nicht ausgelöst und die Bilder laden mit ihrem normalen src-Attribut. Cool, oder?
Danke.
Wenn ich mich nicht irre, gibt es ein Problem mit dem Code-Snippet bei
Ich kann das nicht verstehen.
Was ist in
ONE_OF_OUR_BIGGER_IMAGES? Wie wählen Sie es aus? Außerdem ist sources einenodeList, die meiner Meinung nach keinsrcset-Attribut haben kann.Ich schätze die klare Aufschlüsselung, wie man beim Implementieren von Lazy Loading vorgeht. Für eine wirklich robuste Lösung sollten Sie jedoch in Erwägung ziehen, ein
img-Element in einnoscriptzu setzen. Der Code zum Patchen von Elementen und Attributen würde immer noch sehr ähnlich wie bei Ihnen aussehen.Grundsätzlich glaube ich jedoch, dass Lazy Loading von Bildern die Benutzererfahrung erheblich verschlechtern kann, da es eine kontinuierliche Konnektivität voraussetzt. Jeder mit einer unterbrochenen Internetverbindung, z. B. mit einem iPhone unterwegs in New York, das in die U-Bahn einfährt, kann sich nicht mehr darauf verlassen, dass Seiten vollständig geladen werden. Wenn es mir wirklich wichtig wäre, müsste ich durch eine ganze Seite scrollen, nur um sicherzugehen, dass der Inhalt tatsächlich geladen wurde. Vermutlich sind die U-Bahntunnel in New York nicht die einzigen Orte, an denen die Konnektivität problematisch ist, und ich halte das für einen ausreichenden Grund, Lazy Loading überhaupt nicht zu verwenden. Es verallgemeinert die Annahme einer großartigen Konnektivität, und das scheint ein wenig unrealistisch zu sein.
Als kleine Anmerkung; die Spezifikation besagt, dass ein src-Attribut vorhanden sein muss, um gültig zu sein. Zitat: „Das src-Attribut muss vorhanden sein und eine gültige, nicht leere URL enthalten, die möglicherweise von Leerzeichen umgeben ist und auf eine nicht-interaktive, optional animierte Bildressource verweist, die weder paginiert noch skriptgesteuert ist.“ Browser werden dies zwar nicht beanstanden, aber es ist vielleicht gut, dies für das erste Beispiel zu berücksichtigen.
Ich stimme zu. Ich finde Lazy Loading aus diesem Grund etwas unsensibel für Barrierefreiheit, was… ironisch ist, nehme ich an, angesichts seines beabsichtigten Zwecks.
Selbst wenn es mit 100%iger Konnektivität implementiert wird, empfinde ich es als nervige Benutzererfahrung, aber das ist nur meine Meinung.
Toller kleiner Artikel von Zach mit einigen weiteren/ähnlichen Gedanken
https://www.zachleat.com/web/facepile/
Ich habe mir dasselbe gedacht… dieser Code scheint unvollständig zu sein oder zumindest eine klare Erklärung zu vermissen.
Ich hatte einige Syntaxprobleme mit dieser Funktion. Mit dieser behoben.