Background Image with WebP fallback and data-src

nsilva picture nsilva · Jan 27, 2019 · Viewed 10.1k times · Source

So I am doing some optimisation work on my web site to improve Page Insights scores, two points that I can address are:-

  • Serve images in next-gen formats
  • Defer offscreen images

So images in next-gen formats, I have decided to use WebP but need to include fallbacks so they work in all browsers/devices.

Defer offscreen images; I am using data-src with a bit of JS script to set the background image as the data-src, the JS replaces the initial SRC which is src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="

Taking the below as an example, how would I go about using inline background-image with WebP with fallbacks whilst deferring offscreen images?

HTML

<div id="working-bg" class="parallax" data-src="/wp-content/uploads/2016/08/silva-planning-parralax.jpg" style="background-image: url(/wp-content/uploads/2016/08/silva-planning-parralax.jpg)"></div>

JS for data-src

<script>
function init() {
    var imgDefer = document.getElementsByTagName('img');
    for (var i=0; i<imgDefer.length; i++) {
    if(imgDefer[i].getAttribute('data-src')) {
        imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
    } }

    var imgDeferSpan = document.querySelectorAll('span[data-src]');
    var styleSpan = "background-image: url({url})";
    for (var i = 0; i < imgDeferSpan.length; i++) {
        imgDeferSpan[i].setAttribute('style', styleSpan.replace("{url}", imgDeferSpan[i].getAttribute('data-src')));
    }

    var imgDeferDiv = document.querySelectorAll('div[data-src]');
    var styleDiv = "background-image: url({url})";
    for (var i = 0; i < imgDeferDiv.length; i++) {
        imgDeferDiv[i].setAttribute('style', styleDiv.replace("{url}", imgDeferDiv[i].getAttribute('data-src')));
    }

}

window.onload = init;

</script>

Thanks in advance!

Answer

Peter Svegrup picture Peter Svegrup · Feb 28, 2019

Serve images in next-gen format: Use an image CDN like imagekit.io and get it done for you automatically. Most image CDNs have a free plan that's great for testing and small sites.

Defer offscreen images: Use a ready rolled solution like lozad.js that takes care of both images and background-images. For the background-image you can skip setting an initial inline style as the element has it's size set and will not cause any reflow when the image loads. For <img>s use an empty <svg> as the initial src value where 6 9 in the viewBox below defines the relation between width (6) and height (9) => change those values to fit your context.

data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 9'%3E%3C/svg%3E

Note that lozad.js uses Intersection Observer API that still lacks in browser support so be sure to add a polyfill.

Good luck!