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, fylehq.com.
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
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.
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!