How we created a Medium-like blurry background effect

At Fyle, we focus on providing intuitive, pixel-perfect user interfaces that are also scalable and efficient behind the scenes. 

Our team puts in their heart and soul to keep the Fyle website updated with regular testing sessions, weekly deploys, and performance upgrades. 

In this post, we’ll explore a technique that we employed to create a fast, progressively-enhanced background image for our landing page,

The Problem

Our homepage has a beautiful overlaying white text on a full-screen background image. The problem occurs when someone views this same beautiful landing page on a slow internet connection

A gif of our homepage rendering on a slow internet connection

What you would observe is the line, "Improved financial productivity, cost savings, happy employees," is hidden while the image loaded. White text on a white container won’t be visible, right?

Our problem was due to the large-sized background image we used. It resulted in the site document (DOM) loading faster than the image. On a slow 3G connection, our background image would take longer to load, and users could see parts of the image loading bit-by-bit. This posed a threat to increasing bounce rates on our website. 

One of the hardest tasks for any web developer is to create a site that balances looks and performance. In an optimization battle, user experience should always be the winner against performance. This implies that replacing the existing background image with a low-resolution version is not going to be a smart move.

Why did these problems matter?

Landing pages are a crucial component of online marketing campaigns, specially designed to generate sales or capture leads. These pages are often the primary destination for paid online marketing campaigns. 

Slow load time can critically affect the conversion of visitors to readers/users. Slow pages are also incredibly frustrating to work with and can severely affect business.

Studies suggest that slow load time affects user behavior, bounce rate, and SEO 
Studies show that 47% of users expect a maximum of 2 seconds of load time for an average website.

What did we do? 

We learned that while it may be tempting to pepper your website with beautiful, high-resolution images, it can significantly detract from your website's effectiveness. 

Thus, we came up with something so that users would not have to see a jigsaw puzzle render bit-by-bit in front of them. We served a highly compressed image at first and then switched it with a larger one once it rendered. This is what we call "Low-Quality Image Placeholders" (LQIP). 

The idea is similar to Medium's, serving an image with the same dimensions but with higher compression. With this quick hack, users can see a blurred image for a moment before the sharper image loads. (If this does not happen, try reloading the page with an empty cache.) :)

Sounds good? Let’s get coding!

1. Get a tiny, optimized version of the actual image

First of all, we need a preview version of the image. This should be very small in size, preferably less than 1KB. You can use any free online compressor tool; I used compress-or-die. It is fast, easy, and has various options like size, dimensions, and color quality of the compression. 

With this, we have a low-resolution blurred image as our background. This is perfect for the first seconds when the page is loading. This also distracts users as it acts as a decent cover-up for the actual background.

That is the minified version of our original image. Size; just 365 bytes!

2. Apply non-blocking background image

Next up, use CSS to set this tiny image as the background and stretch it to fill the entire window:

background-color: #6F718F ;

background-image: url(‘ hero-bg-lg-mini.png’) ; 

background-size: cover ; 

Tip: Always set a background-color to be used if the image is unavailable.

We did not use a <img> tag to set the background as it might be blocking. Some Javascript code might be listening for the window onload event. If we were to use a large background in a <img> tag, it may delay the execution and prevent the user from interacting with the page.

3. Load the high-resolution image asynchronously in the background

Get the URL to the large image from the inline CSS, and preload it using JavaScript. If the script fails for some reason, no harm, no foul – the blurred background image is still there, looking pretty cool. 

To accomplish this, I used the following javascript function, which is called the inside onload event. This helps our script to not render-block our page content.

The imageBlurEffect function scans the DOM for any ‘async-image’ class. After that, it will load all the images provided to the data-src attribute on these elements. Once an image is loaded, it will replace either the source of the image tag or the background image of not an IMG element.

Tip: Make sure you remove the async-image class from containers as we don’t need it anymore. (This can be used to apply smooth transitions that give the fade-in/out effects.)


The result

We improved user experience, decreased load time, made Fyle more accessible for users without a fast internet connection, and possibly even improved our ranking on Google! (Speed is a landing page factor for Google Search and Ads)

That’s a significant improvement for a small change!

Aikansh Garg

I am a Member of Technical Staff at Fyle. Away from work, I love to run, work out, and play chess!

More of our stories from

Demystifying Class Variables In Python

Understanding class variables in python

Interview Experience: Backend Engineering Internship at Fyle

Wanna know the secret to crack backend engineering interviews? Learn them here and intern at Fyle!

The curse of being a Senior Engineer, how to deal with timelines, frustrations, etc

Being a good developer is 50% skill and 50% emotional support; here's my secret to balancing both at the right amount!

How did I build cropping of receipts in the mobile app?

Follow Yash's journey of what it takes to reduce manual work for our customers when receipts come in all shapes and sizes!

How did we increase Data Extraction accuracy by a whopping ~50%?

Wanna know the secret of data extraction, the complex machine learning models we use, the experiments we did? Read on...

The not so secret sauce of my work

From chaos to clarity, follow Chethan's not so secret sauce to excelling at work!

From Zero to Hero: The Policy Tests Journey!

The story of policy tests at Fyle

How Fyle changed my life from a naive intern to a confident Engineering Lead

A blogpost that documents Shwetabh's journey at Fyle.

Vikas Prasad @ Fyle

This document is a user guide to Vikas at work.

Gokul K's README

This document is a user guide to Gokul at work.


All Topics