DEV Community

Cover image for Lazy Loading in images with React JS 😴
Franklin Martinez
Franklin Martinez

Posted on

Lazy Loading in images with React JS 😴

Lazy Loading is very important nowadays to improve the performance of your website. Performing image optimization helps your website to be faster, have better SEO and helps to improve user experience.
This time you will learn how to lazy load images in an application with React JS.

Any kind of feedback is welcome, thanks and I hope you enjoy the article.πŸ€—

Β 

Table of Contents.

πŸ“Œ What is Lazy Loading?

πŸ“Œ Benefits of Implementing Lazy Loading

πŸ“Œ Technologies to be used.

πŸ“Œ Creating the project.

πŸ“Œ Implementing Lazy Loading.

πŸ“Œ First steps.

πŸ“Œ Displaying images without implementing lazy loading.

πŸ“Œ Displaying images implementing lazy loading.

πŸ“Œ Conclusion.

Β 

πŸ’€ What is Lazy Loading?

Generally, when a user visits a website, all the content of the page is downloaded and displayed immediately, even though there is no guarantee that the user will consume it. As a result, there is a loss of memory and bandwidth.

And this is where lazy loading appears, which is a strategy that delays the loading of some files, such as images, only until the user needs them depending on their activity and navigation in your application. Normally these files are only loaded when they are in view of the user.

πŸ’€ Benefits of Implementing Lazy Loading.

  • Achieve an ideal balance between the content positioned on the site and the final experience, to achieve relevant value delivery.

  • Faster and more optimized connections, since only what is displayed is loaded.

  • Increased user retention by offering efficient loading and no delays.

  • Resource savings by using only what needs to be displayed.

  • Offers a differentiated experience, especially to users with slow connections.

  • Optimizes the use of user resources, such as battery, mobile data, time, among others.

πŸ’€ Technologies to be used.

  • ▢️ React JS (v 18)
  • ▢️ Vite JS
  • ▢️ TypeScript
  • ▢️ CSS vanilla (You can find the styles in the repository at the end of this post)

πŸ’€ Creating the project.

We will name the project: lazy-img (optional, you can name it whatever you like).

npm init vite@latest
Enter fullscreen mode Exit fullscreen mode

We create the project with Vite JS and select React with TypeScript.

Then we run the following command to navigate to the directory just created.

cd lazy-img
Enter fullscreen mode Exit fullscreen mode

Then we install the dependencies.

npm install
Enter fullscreen mode Exit fullscreen mode

Then we open the project in a code editor (in my case VS code).

code .
Enter fullscreen mode Exit fullscreen mode

πŸ’€ Implementing Lazy Loading.

Nowadays, we can implement lazy loading in the simplest way, just by attaching the loading attribute with the value of lazy to our img or frame tag in HTML:

<img src="image.jpg" alt="Image Alt" loading="lazy" />

<iframe src="iframe" loading="lazy"></iframe>
Enter fullscreen mode Exit fullscreen mode

But this does not work in all browsers. So in these cases, we will need an external package.

πŸ’€ First steps.

We will install: react-lazy-load-image-component.

This popular library provides image rendering capabilities and effects that you can quickly and easily implement in your own React applications.

We install the package:

npm i react-lazy-load-image-component
Enter fullscreen mode Exit fullscreen mode

Nota: If you will use it with TypeScript, you have to install its type definition file:

npm i -D @types/react-lazy-load-image-component
Enter fullscreen mode Exit fullscreen mode

Now in our src/App.tsx file we delete everything and add only a new component that renders a title.

const App = () => {
  return (
    <div>
      <h1><span>Lazy Loading Images</span> πŸ–ΌοΈ</h1>
    </div>
  )
}
export default App
Enter fullscreen mode Exit fullscreen mode

title

πŸ’€ Displaying images without implementing lazy loading.

First we generate a function that returns a certain number of elements in order to map those elements and display the images based on the number of elements.

const generateArray = (items: number) => [...Array.from(Array(items).keys())];
Enter fullscreen mode Exit fullscreen mode

Now we call the function generateArray to generate in this case 15 elements and we traverse it with the map method and render a normal image. I get the images from this page https://picsum.photos/

const generateArray = (items: number) => [...Array.from(Array(items).keys())];

const App = () => {
  return (
    <div>
      <h1><span>Lazy Loading Images</span> πŸ–ΌοΈ</h1>

      <div className="container-images">
        {
          generateArray(15).map(i => (
            <img
              key={i}
              src={`https://picsum.photos/id/${i}/500`}
              alt={`Image Alt-${i}`}
              className="img-lazy"
              width={700} height={500}
            />
          ))
        }
      </div>
    </div>
  )
}
export default App
Enter fullscreen mode Exit fullscreen mode

With this, the 15 images would appear downwards. And for the moment we only see one on our screen.
images

We noticed something when inspecting our site's network.
images

The images all loaded correctly, even though we are only seeing a single image, and that's the problem, it increases our initial loading speed, therefore the page loads slower and the user gets bored and leaves our website!

πŸ’€ Displaying images implementing lazy loading.

The solution is to implement lazy loading.

To do this we import the component from the package we previously installed and just change the img tag to LazyLoadImage.

import { LazyLoadImage } from "react-lazy-load-image-component";

const generateArray = (items: number) => [...Array.from(Array(items).keys())];

const App = () => {
  return (
    <div>
      <h1><span>Lazy Loading Images</span> πŸ–ΌοΈ</h1>

      <div className="container-images">
        {
          generateArray(15).map(i => (
            <LazyLoadImage
              key={i}
              src={`https://picsum.photos/id/${i}/500`}
              alt={`Image Alt-${i}`}
              className="img-lazy"
              width={700} height={500}
            />
          ))
        }
      </div>
    </div>
  )
}
export default App
Enter fullscreen mode Exit fullscreen mode

This component also allows us to display a placeholder while the image is loading. Just add the placeholderSrc property.

In addition, it also has a property to add a certain animation initially before it is loaded and removes it when the image is completely loaded, for it adds the effect property. But to use it you need to import the css of that effect.

import { LazyLoadImage } from "react-lazy-load-image-component";

import 'react-lazy-load-image-component/src/effects/blur.css';

const generateArray = (items: number) => [...Array.from(Array(items).keys())];

const App = () => {
  return (
    <div>
      <h1><span>Lazy Loading Images</span> πŸ–ΌοΈ</h1>

      <div className="container-images">
        {
          generateArray(15).map(i => (
            <LazyLoadImage
              key={i}
              src={`https://picsum.photos/id/${i}/500`}
              alt={`Image Alt-${i}`}
              className="img-lazy"
              width={700} height={500}
              placeholderSrc={placeholder}
              effect='blur' // opacity | black-and-white
            />
          ))
        }
      </div>
    </div>
  )
}
export default App
Enter fullscreen mode Exit fullscreen mode

And our website is ready.

final

And if we now look at the development tools in the network tab, we will see that the loading time of the application has been reduced by almost half, this is because only the images that are in view are loaded and as the user scrolls through the website, the other images will be loaded.

net

πŸ’€ Conclusion.

Optimizing images is a good practice that has to be implemented in your websites, to create a better experience for the user and also thinking about mobile devices.

I hope you liked this post and that it has helped you to understand and put into practice this Lazy Loading technique, with which you notice incredible changes in the performance of your app. πŸ€—

If you know any other different or better way to perform lazy loading, feel free to leave it in the comments πŸ™Œ.

I invite you to check my portfolio in case you are interested in contacting me for a project!. Franklin Martinez Lucas

πŸ”΅ Don't forget to follow me also on twitter: @Frankomtz361

Top comments (12)

Collapse
 
koire profile image
Koire • Edited

I have to say, it's so nice that "lazy" finally is an attribute.
Using the intersect API to judge when to load an image was so hard in the past.
Thanks for sharing "new" knowledge when you discovered it!

edit--
I meant new for you and others, not that it's not good/bad, just new for people

Collapse
 
robole profile image
Rob OLeary • Edited

Be careful not to lazy load images above the fold (on initial screen), this will have a negative impact on page loading times.

Collapse
 
franklin030601 profile image
Franklin Martinez

Thanks for the tip, by the way, how would you avoid loading images above the fold? πŸ€”

Collapse
 
robole profile image
Rob OLeary • Edited

Don't automate blindly by adding lazy loading to every image. When you are writing your HTML, don't make hero images lazy loading candidates!

If you want you want a smart way to automate it completely, then that is tricky. You only know if something is above the fold when the styles are computed.

Collapse
 
flash010603 profile image
Usuario163

I really liked this article, really useful, thanks for sharing.

Collapse
 
prom_ayush profile image
Ayush Porwal • Edited

Hi, the placeholderSrc, placeholder, effect properties didn't seem to work for me. I was trying this article on stackblitz: (Blur might be working but the other two surely arent)

Collapse
 
franklin030601 profile image
Franklin Martinez

the placeholderSrc property is a string, but it must be a URL of some other image

Collapse
 
joserocha profile image
jose-rocha

Tks, congrulations from post!

Collapse
 
wilmela profile image
Wilmela

Good job.

Collapse
 
onfuns profile image
onfuns

Good

Collapse
 
aradwan20 profile image
Ahmed Radwan

Great article, good job

Collapse
 
pahund profile image
Patrick Hund

Great article! πŸ‘πŸ»