What is Lazy Loading or loading on demand?
About
A Lazy loading method will fetch the resource (image, javascript module, advertisements) in the web browser window when needed.
When needed means for media such as image:
- when they will become visible to the user
- when the code is executed (code splitting)
Lazy loading is a technique that defers loading of non-critical resources at page load time.
Instead, these non-critical resources are loaded at the moment of need.
Where images are concerned, “non-critical” is often synonymous with “off-screen”.
Solutions
Markup
HTML Element may have a lazy loading attribute.
Example with the loading attribute for img and iframe
<img src="image.png" srcset="image.png 1000w, image-2x.png 2000w" loading="lazy">
ViewPort detection
Solutions for detecting if an element is visible in the viewport (in order to lazy-load its content)
Dom API
Solutions have often listened for scroll or resize events, then used DOM APIs like getBoundingClientRect() to calculate where elements are relative to the viewport. This works, but is not efficient. It have been error-prone, often causing the browser to become sluggish.
Web Api: IntersectionObserver
IntersectionObserver is a browser API that allows us to efficiently detect when an observed element enters or exits the browser's viewport.
const observer = new IntersectionObserver(entries => {
const entry = entries[0];
if (entry.isIntersecting) {
document.body.style.backgroundColor = 'black';
document.body.style.color = 'white';
} else {
document.body.style.backgroundColor = 'white';
document.body.style.color = 'black';
}
});
observer.observe(div, {
threshold: 1.0
});
// observer.disconnect();
Example
Image and video with Library
Image may be now lazy-loaded by the browser thanks to the new loading attribute.
Library for image and video by popularity
- More …
Example from Lazy Loading Images and Video after the DOMContentLoaded event.
<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">
document.addEventListener("DOMContentLoaded", function() {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
if ("IntersectionObserver" in window) {
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Possibly fall back to a more compatible method here
}
});
Code
See:
Ads
Lazy loading of ads ad