How to Progressively Load Images in React using Hooks
The popular way of loading images, React style
Have you stared at those loading spinners on your screen while waiting for an image to load? Whether they are simple, fancy, or animated, they are still boring and frustrating. 😑

Loading a blurred image first enhances the UX and reduces a website’s loading time significantly. After thorough research, I realized that loading images progressively is easier said than done. However, with the power of React hooks, the process becomes extremely easy and hassle-free. Its reusable functional component can work tricks and can be seamlessly used throughout the project.
The Core Logic
Start off by loading a placeholder image in the browser and start the asynchronous call in order to load the original image. Once the original image is loaded, replace the placeholder image with the original image.
If you are wondering how to make the placeholder image then begin by resizing the image while maintaining the aspect ratio. Make the image as small as possible. For demo purposes, I have resized the original image of resolution 1920*2876 by reducing its width to 5px and adjusting it’s height accordingly. As a result, you can achieve a drastic 99% reduction, leaving the image size to approximately 4kB! 😄

In real-world applications, you don’t want to resize the image manually. Companies like Trello, Slack, Unsplash, etc implement services that will automatically resize the images and then send both the original and placeholder images directly to the frontend for display.
Since we are already implementing this using React hooks we will have a built-in advantage over class components. Additionally, using React.memo will throw in an added performance boost.
Making the Reusable Functional Component.
I have created a reusable functional component named ImageLoad
which takes three arguments namely the original image, the placeholder image, and an alt text.
The useState
hook returns a tuple where the first parameter is the variable name and the second parameter is the function to update that particular variable. We can destructure the tuple using ES6 syntax. Moreover, useState
also has the ability to take an optional default argument.
- In the first line, we are going to implement a
useState
React hook to store and update the loading state. The default value for the loading state is set to true. - In the second line, the
useState
React hook is implemented to initialize the state with a placeholder image as the default value and to store and update the src of the image. - Afterward, we implement the
useEffect
hook to load the image asynchronously and passsrc
as the dependency. This allows it to work similarly to the lifecycle method ofcomponentDidMount
and re-runs only when the value of the src is changed. - The above
useEffect
will fire only after the code inside the return statement is executed. Similar to the class component, where the render method is executed before running thecomponentDidMount
method. The user will be shown with a blurred placeholder image first. - Finally, once the original image is loaded inside the
useEffect
hook, theupdateSrc
method will update the placeholder image with the original image in the state. As a result, the component is re-rendered and the original image is displayed to the user.
The purpose of using React.memo is to avoid any re-render, provided the props passed, remain unchanged.
Component Declaration
Import the ImageLoad component and declare it as follows.
<ImageLoad
src="original-image.jpg"
placeholder="placeholder.jpg"
alt="Decription"
/>
Working Demo
Github Repo
Conclusion
Progressive loading is an excellent way to achieve great UX, especially during a slow internet connection. It is not only visually appealing to the users but it also allows them to know what to expect on their screen. React hooks makes the process concise and clear as well as aids in performance improvement.
For further enhancements, you can also try lazy loading, so that images are loaded only when they are visible in the browser viewport.
I hope you find this helpful! Thank you for reading.