
Afbeeldingen horen tot de populairste contenttypes op het web, en daardoor wordt de laadtijd van je pagina’s al snel een probleem.
Zelfs netjes geoptimaliseerd kunnen afbeeldingen flink zwaar uitvallen. Dat gaat ten koste van de tijd die bezoekers moeten wachten voordat ze bij de inhoud van je site kunnen. De kans is groot dat ze ongeduldig worden en ergens anders verder klikken, tenzij je een manier vindt om afbeeldingen te laden die de ervaren snelheid niet in de weg zit.
In dit artikel ontdek je vijf aanpakken voor lazy loading van afbeeldingen die je aan je gereedschapskist voor webperformance kunt toevoegen om de gebruikerservaring op je site te verbeteren.
Wat is lazy loading?
Bij lazy loading laad je afbeeldingen asynchroon, dus pas nadat de rest van de content geladen is, of zelfs voorwaardelijk: alleen wanneer ze in het browservenster verschijnen. Scrolt de gebruiker niet tot onderaan de pagina, dan worden de afbeeldingen daar dus nooit geladen.
Heel wat websites werken zo, en op sites met veel beeld valt het extra op. Blader eens door je favoriete jachtgebied voor foto’s op hoge resolutie en je merkt meteen dat de site maar een beperkt aantal afbeeldingen laadt. Terwijl je scrolt, zie je hoe de placeholders zich snel vullen met de echte afbeeldingen. Let bijvoorbeeld op het laden van Unsplash.com: zodra je dat deel van de pagina in beeld scrolt, wordt de placeholder vervangen door de foto op volledige resolutie.
Waarom zou je afbeeldingen lazy laden?
Er zijn minstens twee uitstekende redenen om lazy loading van afbeeldingen op je site te overwegen:
- Gebruikt je site JavaScript om content te tonen of om gebruikers functionaliteit te bieden, dan wordt het laden van de DOM snel kritiek. Scripts wachten vaak tot de DOM volledig geladen is voordat ze beginnen te draaien. Op een site met veel afbeeldingen kan lazy loading – afbeeldingen asynchroon laden – het verschil maken tussen bezoekers die blijven en bezoekers die je site verlaten.
- De meeste lazy-loadoplossingen laden een afbeelding pas als de gebruiker tot in de viewport gescrold is. Komt hij daar nooit, dan wordt die afbeelding ook nooit geladen. Dat scheelt aanzienlijk in bandbreedte, en daar zullen de meeste gebruikers je dankbaar voor zijn, zeker wie het web bezoekt op een mobiel apparaat of via een trage verbinding.
Lazy loading van afbeeldingen draagt bij aan de performance van een site, maar wat is de beste aanpak?
Een perfecte methode bestaat niet.
Leef en adem je JavaScript, dan is je eigen lazy-loadoplossing schrijven geen enkel probleem. Niets geeft je meer controle dan zelf iets bouwen.
Je kunt ook het web afstruinen op zoek naar bruikbare aanpakken en daarmee gaan experimenteren. Dat heb ik gedaan, en zo vond ik deze vijf interessante technieken.
#1 Native lazy loading
Native lazy loading van afbeeldingen en iframes is bijzonder prettig. Simpeler dan de markup hieronder wordt het niet:
<img src="myimage.jpg" loading="lazy" alt="..." />
<iframe src="content.html" loading="lazy"></iframe>
Zoals je ziet: geen JavaScript, geen dynamische wissel van het src-attribuut van de afbeeldingen en de iframes. Gewoon goede, ouderwetse HTML.
Het attribuut loading geeft je de mogelijkheid om afbeeldingen en iframes buiten beeld uit te stellen tot de gebruiker naar hun plek op de pagina scrolt. loading kan drie waarden aannemen:
lazy: precies wat je wilt voor lazy loadingeager: draagt de browser op de opgegeven content meteen te laden.auto: laat de keuze om al dan niet lazy te laden aan de browser.
Deze methode kent geen concurrentie: geen overhead, schoon en eenvoudig. Al hebben de meeste grote browsers op het moment van schrijven goede ondersteuning voor het attribuut loading, alle browsers doen nog niet mee.
#2 Lazy loading met de Intersection Observer API
De Intersection Observer API is een moderne interface waarmee je afbeeldingen en andere content lazy kunt laden.
Zo stelt MDN deze API voor:
Met de Intersection Observer API kun je asynchroon de veranderingen observeren in de doorsnede van een doelelement met een voorouderelement of met de viewport van een document op het hoogste niveau.
Met andere woorden: wat asynchroon geobserveerd wordt, is de doorsnede van het ene element met het andere.
Stel dat je een fotogalerij lazy wilt laden. De markup van elke afbeelding ziet er dan zo uit:
<img data-src="image.jpg" alt="test image">
Het valt je op dat het pad naar de afbeelding in een data-src-attribuut staat en niet in een src-attribuut. De reden: met src zou de afbeelding meteen laden, en dat is nu net niet de bedoeling.
In de CSS geef je elke afbeelding een min-height van bijvoorbeeld 100px. Zo krijgt elke plek voor een afbeelding (het img-element zonder src-attribuut) een verticale afmeting:
img {
min-height: 100px;
/* meer stijlen hier */
}
In je JavaScript maak je vervolgens een config-object en registreer je dat bij een instantie van intersectionObserver:
// een configuratieobject maken: rootMargin en threshold
// zijn twee properties die de interface aanbiedt
const config = {
rootMargin: '0px 0px 50px 0px',
threshold: 0
};
// het config-object registreren bij een instantie
// van intersectionObserver
let observer = new intersectionObserver(function(entries, self) {
// over elke entry itereren
entries.forEach(entry {
// alleen de afbeeldingen verwerken die in beeld komen.
// isIntersecting is een property die de interface aanbiedt
if(entry.isIntersecting) {
/. / Fonction personnalisée qui copie le chemin vers l'image
// van data-src naar src
preloadImage(entry.target);
// de afbeelding staat er nu, stop met observeren
self.unobserve(entry.target);
}
});
}, config);
Tot slot loop je over al je afbeeldingen en voeg je ze toe aan die instantie van iterationObserver:
const imgs = document.querySelectorAll('[data-src]');
imgs.forEach(img {
observer.observe(img);
});
De voordelen van deze oplossing: ze is eenvoudig te implementeren, ze is efficiënt, en je laat intersectionObserver het zware rekenwerk doen.
Daar staat tegenover dat de Intersection Observer API weliswaar in de recentste versies van de meeste browsers zit, maar niet door alle browsers even consequent wordt ondersteund. Gelukkig is er een polyfill beschikbaar.
#3 Lozad.js – lazyload in JS
Een snel en makkelijk alternatief om lazy loading van afbeeldingen te implementeren, is een JS-library het zware werk laten opknappen.
Lozad is een zeer performante, lichte en configureerbare lazy loader in puur JavaScript, zonder enige dependency. Je laadt er afbeeldingen, video’s, iframes en veel meer lazy mee, en hij gebruikt de Intersection Observer API.
Je haalt Lozad binnen met npm of Yarn en importeert hem met de module bundler van je keuze:
npm install --save lozad
yarn add lozad
import lozad from 'lozad';
Je kunt de library ook via een CDN ophalen en onderaan de HTML-pagina in een < script> toevoegen:
<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
Voor een basisimplementatie geef je de asset in je markup vervolgens de klasse lozad:
<img class="lozad" data-src="img.jpg">
Tot slot instantieer je Lozad in je JS-bestand:
const observer = lozad();
observer.observe();
Alle details over het gebruik van de library vind je in de GitHub-repository van Lozad.
Wil je je niet in de binnenkant van de Intersection Observer API verdiepen, of zoek je gewoon een snelle implementatie die op allerlei soorten content werkt, dan is Lozad een uitstekende keuze.
Let alleen op de browserondersteuning en combineer deze library eventueel met een polyfill voor de Intersection Observer API.
#4 Lazy loading met een vervaagde afbeelding
Het eerste wat je ziet is een wazige kopie op lage resolutie, terwijl de versie op hoge resolutie lazy wordt geladen:


Je kunt afbeeldingen op verschillende manieren lazy laden met dit fraaie blur-effect.
Dit zijn alle voordelen van deze oplossing:
- Performance: slechts 463 bytes CSS en 1.007 bytes geminificeerde JavaScript.
- Ondersteuning voor retinaschermen
- Zonder dependency: geen jQuery of andere libraries of frameworks nodig.
- Progressive enhancement om oudere browsers en falend JavaScript op te vangen.
Voor zo’n effect kun je progressive-image.js downloaden.
#5 Yall.js – lazyload in JS
Yall is een lazy-loadscript met veel mogelijkheden voor afbeeldingen, video’s en iframes. Het gebruikt de Intersection Observer API en valt waar nodig slim terug op klassieke technieken met eventafhandeling.
Neem je Yall op in je document, dan initialiseer je het zo:
<script src="yall.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", yall);
</script>
Om vervolgens een eenvoudige img lazy te laden, heb je in je markup alleen dit nodig:
<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">
Let op het volgende:
- je geeft het element de klasse lazy
- de waarde van
srcis een placeholderafbeelding - het pad naar de afbeelding die je lazy wilt laden staat in het
data-src-attribuut
Voordelen van Yall zijn onder meer:
- uitstekende performance dankzij de Intersection Observer API
- fantastische browserondersteuning (tot en met IE11)
- geen verdere dependencies nodig
Wil je weten wat Yall verder te bieden heeft, of zoek je complexere implementaties, kijk dan gerust op GitHub.
Conclusie
Dat waren ze: vijf methodes voor lazy loading van afbeeldingen waarmee je in je eigen projecten kunt experimenteren en testen.


