Coding

How to use lazy load for background images

posted on by - 409 views

Today’s world wide web is full of images, we know that. For that reason, there’s a risk web developers have to face: what if the web page we’re working on has just too many images, and requires high loading times, especially for slow mobile connections? A way to solve the problem could be using lazy load, a technology that makes images appear only when they’re in the user viewport. In other words: let’s load images only when needed, when they’re actually seen by the viewer. And while there are many WordPress plugins that allow us to do that, the solution it’s a little bit different if we’re talking about background images.

So, in this article, we will learn…

How to apply lazy load for background images in WordPress

To achieve this, we’re first going to use a polyfill called IntersectionObserver. It’s a piece of js code we can find here. So, first things first, let’s enqueue it in our WordPress environment.

Once it’s done, we can go work on our HTML code. Let’s say we have a div loading a background image, something like this:

<div class="divWithBg" style="background-image: url(http://mywebsite.com/images/wonderful-background.png);"></div>

Right? Yeah, that’s the usual way we’re writing divs with background images.
Now, let’s tweak it a little bit to make it ready for what we’re going to do:

<div class="divWithBg lazyDiv" data-lazybg="http://mywebsite.com/images/wonderful-background.png" style=""></div>

Uh? What did we do here?

Let’s see:

  1. First of all, we added the class lazyDiv, that will help us identify the elements we need;
  2. Then, we deleted the inline style: now it’s just an empty attribute;
  3. Lastly, we added another attribute called data-lazybg, where we put the address of our background image.

Now, let’s go write some javascript using the polyfill we just loaded.

let LazyObserver = new IntersectionObserver( function( entries, observer ) {
    entries.forEach( function( entry ){
        if( entry.isIntersecting ){
            let LazyObject = entry.target;
            if( !( LazyObject.dataset.lazybg == '' ) ){
                var bg_src = LazyObject.dataset.lazybg;
                LazyObject.style.backgroundImage = 'url(' + bg_src + ')';
                LazyObject.classList.remove( "lazyDiv" );
                LazyObject.dataset.lazybg = '';
                LazyObserver.unobserve( LazyObject );
            }
        }
    });
},{ rootMargin: "0px 0px 0px 0px" });

document.addEventListener( "DOMContentLoaded", function() {
    // Call the function when DOM is loaded
    observe_dom();
});

function observe_dom(){
    // We can call this function wherever we need, for example when other elements are loaded in the page (e.g.: ajax calls...)
    var LazyObjects = [].slice.call( document.querySelectorAll( ".lazyDiv" ) );
    LazyObjects.forEach( function( LazyObject ){
        LazyObserver.observe( LazyObject );
    });
}

Notice that we created a function called observe_dom(), that we can use when other elements are being loaded after, like with an ajax call.

So that should be it! Now, with the lazy load for background images, they will only be loaded when actually in the viewport.

Big shoutout to HU ist Sebastian for providing this useful solution on StackOverflow.