Because Performance Matters

Lazy Loading With Low Quality Image Placeholders

By Shawn MaustAugust 31, 2016

When it comes to displaying a lot of images on a web page, lazy loading offers some great benefits. But there is a fine balance between loading only what’s necessary, and ensuring a smooth user experience. For instance, if the user scrolls fairly quickly, or if there is latency in loading the images, it’s possible that some images will not be fully loaded by the time they enter the viewport. One technique – using low quality image placeholders – tries to find the middle ground between keeping the user experience as smooth as possible without sacrificing all the performance gains lazy loading provides. We’ll take a look at how in this post.

Low Quality Image Placeholders

Generic Placeholders

It’s not uncommon to either load a blank (transparent) image or a generic placeholder as the initial image when utilzing lazy loading. This placeholder has an extremely small file size, and can be created to match the proportions of the final image so the page layout doesn’t reflow when the images are lazy loaded. But although these kinds of placeholder may be quite lightweight, the content of the image doesn’t necessarily match the content of the final image. So if the final image isn’t quite loaded as the user scrolls by, the user will either see a blank space where the image will (soon) appear, or some kind of generic placeholder that will eventually be replaced.

Low Quality Placeholders

The “low quality image placeholder” option is simply to use super low quality versions of the final image as the placeholder. This could be as simple as taking the image and making a smaller version of it (say 200px wide instead of 800px wide), and then using CSS to scale up the image to fill the space. These images would weigh more than a blank or generic placeholder would, but they would still weigh significantly less than the final version. The advantage over a generic placeholder, though, is the content of the photo is exactly the same as the final image. The only difference is that the initial one is of a much lower quality.

Hiding Pixelation

The lower quality image is bound to be pixelated – at least way more so than the final image. One way to work around this lack of quality is to use a CSS filter to blur the low quality image until the higher quality loads. The blur effect can then be transitioned off, providing a nice effect.

For instance, if we’re using the lazy sizes plugin for the lazy loading, we could do something like this (the amount of blur, and the duration fo the transition, can all be adjusted to get the effect you’re looking for):

.blur {
    -webkit-filter: blur(3px);
    filter: blur(3px);
    transition: filter 600ms, -webkit-filter 600ms;

.blur.lazyloaded {
    -webkit-filter: blur(0);
    filter: blur(0);

<img src=“low-res-image.jpg" data-src="image.jpg" class="lazyload blur" />


Here’s a fuller example with several images being lazy loaded, and a slight blur being added to the initial low quality placeholders.

See the Pen dpbdyN by Shawn Maust (@afasterweb) on CodePen.

Adding the blur makes it less evident that the initial image is a low quality image. And by using CSS, we can also have control over the transition to the final image.


The upside to this technique is the user doesn’t experiences any blank spaces or generic placeholders if they scroll too quickly – all of the images will just have smaller versions already in place.

One downside, though, is each image now requires one more network request, which is something that definitely needs to be factored in. The other downside is that if we want to use the blur effect, there are some browsers that don’t support CSS filters (currently support is at ~83%), so a small percentage of users wouldn’t get that effect.

Using this technique ultimately involves trade-offs. It’s a nice technique to have in your toolkit when you’re lazy loading a number of images, and want to prevent generic/blank placeholders as the user scrolls. But since each situation is different, the decision to use it or not should be decided on whether the benefits outweigh the costs in your particular case.