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:
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”.
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">
Solutions for detecting if an element is visible in the viewport (in order to lazy-load its content)
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.
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();
Image may be now lazy-loaded by the browser thanks to the new loading attribute.
Library for image and video by popularity
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
}
});
See:
Lazy loading of ads ad