Hello Sunil

Optimizing Image Loading with React: A Guide to Using React Lazy Load Image Component

In modern web development, performance is key to delivering a smooth user experience. One common performance issue is slow image loading, especially when a page contains many images.

In this blog, we’ll explore how to tackle this problem using the react-lazy-load-image-component library, which can significantly enhance your application’s loading speed and overall user experience.

When a webpage includes many images, loading all of them at once can slow down the page, leading to a poor user experience. Images that are not immediately visible to the user add unnecessary load time and can affect the page’s performance. This is where lazy loading becomes essential.

Lazy loading is a technique where images (or other resources) are loaded only when they come into the viewport. This means that images that are off-screen won’t be loaded until the user scrolls down to them, which reduces initial load time and saves bandwidth.

The react-lazy-load-image-component library is a powerful tool that simplifies lazy loading of images in React applications. It provides an easy-to-use Lazy Load Image component that supports various features like blur-up placeholders, responsive images, and more.

Let’s dive into an example to understand how to use this library effectively. We’ll use it to build a cake product page where images are loaded lazily.

Installation

To get started, you need to install the library:

npm i react-lazy-load-image-component

Oher necessary packages (Optional):

npm install react-grid-system styled-components

The Cake ProductPage component displays a gallery of images using a responsive grid layout. Here’s the code:

ProductPage.jsx

// Import Library
import React from "react";
import { Container, Row, Col } from "react-grid-system";

// Import Component
import Card from "./Card";

// Import Images
import Cake1 from "../images/Cake1.jpg";
import Cake2 from "../images/Cake2.jpg";
import Cake3 from "../images/Cake3.jpg";
import Cake4 from "../images/Cake4.jpg";
import Cake5 from "../images/Cake5.jpg";
import Cake6 from "../images/Cake6.jpg";
import Cake7 from "../images/Cake7.jpg";
import Cake8 from "../images/Cake8.jpg";
import Cake9 from "../images/Cake9.jpg";
import Cake10 from "../images/Cake10.jpg";
import Cake11 from "../images/Cake11.jpg";
import Cake12 from "../images/Cake12.jpg";
import Cake13 from "../images/Cake13.jpg";
import Cake14 from "../images/Cake14.jpg";
import Cake15 from "../images/Cake15.jpg";
import Cake17 from "../images/Cake17.jpg";
import Cake18 from "../images/Cake18.jpg";

import Cake1PPlaceholderImg from "../images/Cake1PPlaceholderImg.jpg";
import Cake2PPlaceholderImg from "../images/Cake2PPlaceholderImg.jpg";
import Cake3PPlaceholderImg from "../images/Cake3PPlaceholderImg.jpg";
import Cake4PPlaceholderImg from "../images/Cake4PPlaceholderImg.jpg";
import Cake5PPlaceholderImg from "../images/Cake5PPlaceholderImg.jpg";
import Cake6PPlaceholderImg from "../images/Cake6PPlaceholderImg.jpg";
import Cake7PPlaceholderImg from "../images/Cake7PPlaceholderImg.jpg";
import Cake8PPlaceholderImg from "../images/Cake8PPlaceholderImg.jpg";
import Cake9PPlaceholderImg from "../images/Cake9PPlaceholderImg.jpg";
import Cake10PPlaceholderImg from "../images/Cake10PPlaceholderImg.jpg";
import Cake11PPlaceholderImg from "../images/Cake11PPlaceholderImg.jpg";
import Cake12PPlaceholderImg from "../images/Cake12PPlaceholderImg.jpg";
import Cake13PPlaceholderImg from "../images/Cake13PPlaceholderImg.jpg";
import Cake14PPlaceholderImg from "../images/Cake14PPlaceholderImg.jpg";
import Cake15PPlaceholderImg from "../images/Cake15PPlaceholderImg.jpg";
import Cake17PPlaceholderImg from "../images/Cake17PPlaceholderImg.jpg";
import Cake18PPlaceholderImg from "../images/Cake18PPlaceholderImg.jpg";


const ProductPage = () => {
  return (
    <div>
      <Container>
        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake1}
              placeholderImg={Cake1PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake2}
              placeholderImg={Cake2PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake3}
              placeholderImg={Cake3PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>

        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake4}
              placeholderImg={Cake4PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake5}
              placeholderImg={Cake5PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake6}
              placeholderImg={Cake6PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>

        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake7}
              placeholderImg={Cake7PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake8}
              placeholderImg={Cake8PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake9}
              placeholderImg={Cake9PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>

        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake10}
              placeholderImg={Cake10PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake11}
              placeholderImg={Cake11PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake12}
              placeholderImg={Cake12PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>

        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake13}
              placeholderImg={Cake13PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake14}
              placeholderImg={Cake14PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake15}
              placeholderImg={Cake15PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>

        <Row>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake2}
              placeholderImg={Cake2PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake17}
              placeholderImg={Cake17PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
          <Col xs={4} sm={4} md={4} lg={4} xl={4}>
            <Card
              image={Cake18}
              placeholderImg={Cake18PPlaceholderImg}
              title="Card Title"
              description="This is a description of the card. It can be a few lines long."
            />
          </Col>
        </Row>
      </Container>
    </div>
  );
};

export default ProductPage;

Create a Card component where images will be displayed. Here’s how you can set it up:

Card.jsx

// Import Library
import React, { useState } from "react";
import styled, { keyframes } from "styled-components";
import { LazyLoadImage } from "react-lazy-load-image-component";

// CSS Imports 
import "react-lazy-load-image-component/src/effects/blur.css";

const CardContainer = styled.div`
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  max-width: 300px;
  text-align: center;
  margin-bottom: 50px;
  margin-top: 50px;
`;


const shimmer = keyframes`
  0% {
    background-position: -468px 0;
  }
  100% {
    background-position: 468px 0;
  }
`;

const ShimmerWrapper = styled.div`
  background: #f6f7f8;
  background-image: linear-gradient(
    to right,
    #f6f7f8 0%,
    #edeef1 20%,
    #f6f7f8 40%,
    #f6f7f8 100%
  );
  background-repeat: no-repeat;
  background-size: 800px 200px;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  animation: ${shimmer} 1s linear infinite;
`;

const ImageWrapper = styled.div`
  position: relative;
  width: 100%;
  max-height: 200px;
`;

const Image = styled(LazyLoadImage)`
  width: 100%;
  height: 100%;
  object-fit: cover;
  background-color: #f0f0f0;
  opacity: ${({ isLoaded }) => (isLoaded ? 1 : 1)};
  transition: opacity 0.5s ease;
  position: absolute;
  top: 0;
  left: 0;
`;

const Title = styled.h2`
  font-size: 1.5rem;
  margin: 16px 0 8px;
`;

const Description = styled.p`
  font-size: 1rem;
  color: #666;
  padding: 0 16px;
  margin-bottom: 16px;
`;

const Button = styled.button`
  background-color: #ff7d29;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 10px 20px;
  margin-bottom: 16px;
  cursor: pointer;
  transition: background-color 0.3s ease;

  &:hover {
    background-color: #c9631f;
  }
`;

const Card = ({ image, title, description, placeholderImg }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  
  return (
    <CardContainer>
      <ImageWrapper>
        {!isLoaded && <ShimmerWrapper />}
        <Image
          src={image}
          effect="blur"
          alt={title}
          placeholderSrc={placeholderImg}
          width={300}
          height={200}
          useIntersectionObserver={true}
          onLoad={() => setIsLoaded(true)}
          isLoaded={isLoaded}
        />
      </ImageWrapper>
      <Title>{title}</Title>
      <Description>{description}</Description>
      <Button>Learn More</Button>
    </CardContainer>
  );
};

export default Card;

Explanation

Styled Components: We use styled-components to style our card. The CardContainer provides a border, shadow, and margin, while ImageWrapper and ShimmerWrapper manage image placeholders.

LazyLoadImage: The LazyLoadImage component from react-lazy-load-image-component is used to render the image.

It supports a placeholderSrc prop for the image that will be shown while the actual image is loading. The effect prop with the value “blur” adds a blur effect to the placeholder image.

Shimmer Effect: The shimmer effect is applied using CSS animations, giving users a visual indication that content is loading.

State Management: The useState hook is used to track whether the image has loaded. We show the shimmer effect until the image is fully loaded.

In your App component, import and render the ProductPage component:

App.jsx

import './App.css';
import ProductPage from './components/ProductPage';

function App() {
  return (
    <>
      <ProductPage />
    </>
  );
}

export default App;

Ensure you have a global CSS file for basic styles, including font imports:

App.css

@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');


body {
  font-family: "Poppins", sans-serif
}

Output:

By implementing lazy loading with react-lazy-load-image-component, you can significantly enhance the performance of image-heavy applications, ensuring a smoother and faster user experience.

Feel free to adapt this approach to your own projects, and remember that efficient image handling is just one aspect of creating high-performing web applications.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Similar articles you may like

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.

Add comment

Stay Updated

Want to be notified when our article is published? Enter your email address below to be the first to know.

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.