How to use blur loading to combat a background image bug

FOUC

This was a term I hadn’t before encountered, but was suffering from for the past couple months.

It stands for “Flash Of Unstyled Content“, and it was happening on the Hero section of FLX Squares ever since I published the site.

For a brief moment, users would see a gray background in the Hero section before the background image (set with CSS) loaded. It was just noticeable enough to really, really bug me, but I struggled to come up with a solution.

The FLX Squares site is my baby. I needed the site to look professional and as close to perfect as possible, and FOUC was the main thing standing in my way.

Blur loading to the rescue

I had remembered watching a Web Dev Simplified video on lazy loading images and remembered how he had also ‘blur loaded’ his images in addition to simply lazy loading them.

Since the Hero section is above the fold by definition, I knew lazy loading itself wouldn’t be the solution. But maybe blur loading would be the companion I needed on my Hero’s Journey.

What is blur loading?

Basically, you make a really tiny version (~20px) of your image, maintain the original aspect ratio, overlay it on the desired image, and blur it with a CSS filter function.

Then, only once the desired image loads, display that background image.

I implemented this solution on the FLX Squares site and it loads beautifully, making the site appear lightning fast, despite its score of 73 for performance in Lighthouse.

A consideration for background images

The Web Dev Simplified article was almost perfect for helping me with this problem, but there was one adjustment that needed to be made.

In the article’s JavaScript snippet, they do this:

const blurredImageDiv = document.querySelector(".blurred-img")
const img = blurredImageDiv.querySelector("img")
function loaded() {
  blurredImageDiv.classList.add("loaded")
}

if (img.complete) {
  loaded()
} else {
  img.addEventListener("load", loaded)
}

That’s great for when the desired image is actually in an <img> tag, but that’s not the case with how I implemented the Hero section.

In order to use the complete property, we need an actual html img. But the good news is that we can make one with JavaScript.

We can use the Image constructor to instantiate an HTMLImageElement:

const backgroundImage = new Image();

and then set its src to the path of the desired background image:

backgroundImage.src = '/your-bg-img-path.jpg';
Then we can use the complete property for our logic:
if (backgroundImage.complete) {
    loaded();
  } else {
    backgroundImage.addEventListener("load", loaded);
  }

With this code modified, the rest of the code from the article works as-is for the most part. I had to add “filter: unset” on the blurred image with the loader class, but otherwise it worked perfectly for my use case.