willmahoney
willmahoney

Reputation: 451

How should I implement lazy loading for my images in react?

I'm trying to add lazy loading to my react application as I have over 200 images that I don't need on the initial load. If I lazy load the images, does this mean, they won't be loaded until they're needed on the screen?

I'm currently importing 4 groups of about 50 images into .js files and then adding them to objects so they can be dynamically used in my components. It looks like this...

// SportImages.js file
import Football from './images/football.png
import Cricket from './images/cricket.png
import Soccer from './images/soccer.png
... // another 50 or so imports

export default {
  Football,
  Cricket,
  Soccer,
  ... // another 50 or so files
}

// and then in my component
cards.map(x => {
  return (
    <img src={SportImages[x.image_ref]} />
  )
})

So my question is, should I be using lazy loading in the component file or in the main images file if I want to lazy load every image?

Upvotes: 18

Views: 62352

Answers (4)

Jon Koops
Jon Koops

Reputation: 9261

You can add the loading attribute to your image element to lazy-load the images. A complete explainer guide on this attribute can be found on web.dev.

In your case it would probably look as follows:

cards.map(card => (
  <img src={SportImages[card.image_ref]} loading="lazy" />
))

You should also make sure to specify the width and height attributes so the browser can place the element on the page with the correct dimensions.

Upvotes: 29

Lukas Helebrandt
Lukas Helebrandt

Reputation: 351

As of 2023, all major browsers support the loading="lazy" attribute on the img tag (caniuse), which makes it the easiest way to implement lazy loading of images.

However, because of a bug in Firefox, in order to make it work in Firefox, the loading attribute must be placed before the src attribute.

So, to paraphrase the answer of Jon Koops, until the bug in Firefox is resolved, this is the example that will work across Firefox, Chrome and Safari:

cards.map(card => (
  <img loading="lazy" src={SportImages[card.image_ref]} />
))

If you were to place loading="lazy" after the src attribute, the lazy loading works in Chrome, but not in Firefox.

Upvotes: 5

GMKHussain
GMKHussain

Reputation: 4661

loading='lazy' attribute Safari not supported

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

Try this package:

npm i react-lazy-load-image-component

Example:

import React from 'react';

import { LazyLoadImage, trackWindowScroll } from 'react-lazy-load-image-component';

const Gallery = ({ images, scrollPosition }) => (
  <div>
    {images.map((image) =>
        <LazyLoadImage  scrollPosition={scrollPosition}
            width="100%"
            height="auto"
            src={image.url} />
    )}
  </div>
);
 
export default trackWindowScroll(Gallery);

Upvotes: 1

Gab Agoncillo
Gab Agoncillo

Reputation: 87

You can use this library called react-lazy-load-image-component Import the LazyLoadImage component then use it the render you images

cards.map(card => (
     <LazyLoadImage src={SportImages[card.image_ref]} {...props}/>
  ))

You can also add an effect when lazy loading the images. You can check the documentation of the library here https://www.npmjs.com/package/react-lazy-load-image-component

Upvotes: 2

Related Questions