How to properly lazyload element background image?

How to properly lazyload element background image?

I don’t think you can do that within React, but it is possible with some client side javascript.

Not tested, but should do the job:

document.addEventListener("DOMContentLoaded", function() {
    // handle regular images
    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);
        });
    }

    // handle background images
    var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));
    if ("IntersectionObserver" in window) {
        let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    entry.target.style.backgroundImage = entry.target.src;
                    entry.target.classList.remove("lazy-background");
                    lazyBackgroundObserver.unobserve(entry.target);
                }
            });
        });
        lazyBackgrounds.forEach(function(lazyBackground) {
            lazyBackgroundObserver.observe(lazyBackground);
        });
    }
});

All you need is to modify the HTML for your images and div’s with background images:

<img data-src="/path/to/image.ext" class="lazy" />
<div data-src="/path/to/image.ext" class="lazy-background" />

BTW the above script is based on default behavior of (modern) browsers to identify if something should be loaded. More information about IntersectionOberver and where the script comes from can be found at https://web.dev/lazy-loading-images/

1 Like

Yea! Thank you) But there is a little mistakes in code:

entry.target.style.backgroundImage = entry.target.src;

should be raplaced with

entry.target.style.backgroundImage = `url(${entry.target.dataset.src})`

I’ve created better approach using Frontity hook) Hope it will be usefull)

1 Like