Easy "Blur Up" Image Loading with React Hooks
Published: 2020-07-19 20:57:26

**Nb**. I originally wrote about this technique on my blog, and there are interactive examples there so if you find this interesting [check it out](https://benhoneywill.com/progressive-image-loading-with-react-hooks/)! 😊

## What is "Blurring Up" an image?

Sometimes big images take a bit too long to load, and it can ruin users' first impressions of a site.

"Blurring Up" an image involves initially rendering a very small image, scaling it up and then applying a Gaussian Blur.

This means you get a low-res blurry representation of the image while the full-size image loads, and you never have to worry about your users looking at blank boxes where images should be.

## Implementing this in React

I wanted to create a neat and tidy **reusable** React Hook that I could use in various components for Blur Up image loading. Here is what I ended up with.

```js
import React from 'react';

const useProgressiveImg = (lowQualitySrc, highQualitySrc) => {
  const [src, setSrc] = React.useState(lowQualitySrc);

  React.useEffect(() => {
    setSrc(lowQualitySrc);

    const img = new Image();
    img.src = highQualitySrc;

    img.onload = () => {
      setSrc(highQualitySrc);
    };
  }, [lowQualitySrc, highQualitySrc]);

  return [src, { blur: src === lowQualitySrc }];
};

export default useProgressiveImg;
```

This is a hook which accepts two arguments: a low-quality image `src`, and a high-quality image `src`.

By default this hook will return the `src` of the low-quality pixelated image. Once the higher quality image has loaded, it will return that instead. This is achieved by adding an event listener to a new `Image` object. The `src` attribute of this `Image` is set to the `src` of our __high quality image__, so the event listener fires once the full-size image has loaded.

Once that image has loaded we switch from returning the pixelated image to returning the full-size image.

You may have also noticed that this hook returns a second value, which is an object containing a value I have called `blur`. We can use this to know whether or not we need to "blur" the image. If the current `src` being returned is that of the low-quality image, then we should blur the image, as that is the nasty pixelated one.

##### Usage

Here is an example of how to use this hook to get the desired "blur up" effect.

```js
import React from "react";
import useProgressiveImg from "./useProgressiveImg";

const BlurredUpImage = () => {
  const [src, { blur }] = useProgressiveImg(
    "./tiny.jpg",
    "./large.jpg"
  );

  return (
    <img
      src={src}
      style={{
        width: 200,
        filter: blur
          ? "blur(20px)"
          : "none",
        transition: blur
          ? "none"
          : "filter 0.3s ease-out"
      }}
    />
  )
}
```

In this example `tiny.jpg` should be a very small version of the full-size image `large.jpg`.

I have used inline styles here for simplicity's sake, but you could also use the `blur` value to toggle a class, or pass it in as a prop to a styled component. The important thing here is that we are adding a CSS `blur()` filter if the image hasn't loaded yet. The `transition` makes the transition between the blurred and non-blurred states nice and smooth.

### Thanks for reading

Let me know what you think of this handy hook in the comments.