Every year Google Lighthouse and pagespeed gives me more to do. This time my site was slowed down because of background images not being lazy loaded. I decided to do something about it, just as I had done with Google ads and Disqus being slow. This post is on the styling "background-image" and not on the usage of an image element. This solution requires no external scripts to work and is plain vanilla javascript.
How it works
We add the attribute "lazy-load-background" to the element which we want to have a lazy loaded background. The attributes value is the path to the image we wish to load lazily:
<div lazy-load-background="/some/url/to/your/image.jpg"> </div>
We then get to the javascript part:
var initVisibleBackgrounds = function(){
var currentScroll = document.scrollingElement.scrollTop;
var elements = document.querySelectorAll('[lazy-load-background]');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if ((currentScroll > element.getBoundingClientRect().top - 150)) {
var background = element.getAttribute('lazy-load-background');
element.style.backgroundImage = "url('" + background +"')";
element.removeAttribute('lazy-load-background');
element.setAttribute('lazy-loaded-background', '');
}
}
};
if (elements !== null && elements.length !== 0) {
initVisibleBackgrounds();
window.addEventListener('scroll', function (e) {
initVisibleBackgrounds();
}, false);
}
If we move past the function "initVisibleBackgrounds" to begin with we start by checking if there are any backgrounds to lazy load on the page if not we do nothing (not all my pages have lazy loaded backgrounds). We then fire the method "initVisibleBackgrounds" and also attach it to the scroll bar, so whenever the user scrolls this function is fired. Within "initVisibleBackgrounds" we get all the lazy loadable elements and iterate through them. If the current iterated element is less than 150 pixels from where the user is scrolling we add the background from the attribute "lazy-load-background" as background-image styling to the element.
The end result is shown below:
<div style="background-image: url("/some/url/to/your/image.jpg");" lazy-loaded-background > </div>
That is it
That is all there is to it, I hope you found this simple and helpful and good luck with your page performance improvements. If you have any questions, praise or criticism leave it down below in the comments.