Lazy load your component, image or anything matters the performance.

Overview

Note

This project is now currently maintained by @ameerthehacker, please reach out to him on any issues or help.


react-lazyload Build Status npm version Coverage Status npm downloads

Lazyload your Components, Images or anything matters the performance.

Join the community on Spectrum

Demo

Why it's better

  • Take performance in mind, only 2 event listeners for all lazy-loaded components
  • Support both one-time lazy load and continuous lazy load mode
  • scroll / resize event handler is throttled so you won't suffer frequent update, you can switch to debounce mode too
  • Decorator supported
  • Server Side Rendering friendly
  • Thoroughly tested

Installation

2.0.0 is finally out, read Upgrade Guide, it's almost painless to upgrade! 3.0.0 fixes the findDomNode warning through usage of React ref, and the following are the changes you need to be aware of

  • Now we have an extra div wrapping the lazy loaded component for the React ref to work
  • We can understand that it is an extra DOM node, and we are working to optimize that if possible
  • It might break your UI or snapshot tests based on your usage
  • To customize the styling to the extra div please refer here
  • Found any other problem, please feel free to leave a comment over here
$ npm install --save react-lazyload

Usage

import React from 'react';
import ReactDOM from 'react-dom';
import LazyLoad from 'react-lazyload';
import MyComponent from './MyComponent';

const App = () => {
  return (
    <div className="list">
      <LazyLoad height={200}>
        <img src="tiger.jpg" /> /*
                                  Lazy loading images is supported out of box,
                                  no extra config needed, set `height` for better
                                  experience
                                 */
      </LazyLoad>
      <LazyLoad height={200} once >
                                /* Once this component is loaded, LazyLoad will
                                 not care about it anymore, set this to `true`
                                 if you're concerned about improving performance */
        <MyComponent />
      </LazyLoad>
      <LazyLoad height={200} offset={100}>
                              /* This component will be loaded when it's top
                                 edge is 100px from viewport. It's useful to
                                 make user ignorant about lazy load effect. */
        <MyComponent />
      </LazyLoad>
      <LazyLoad>
        <MyComponent />
      </LazyLoad>
    </div>
  );
};

ReactDOM.render(<App />, document.body);

If you want to have your component lazyloaded by default, try this handy decorator:

import { lazyload } from 'react-lazyload';

@lazyload({
  height: 200,
  once: true,
  offset: 100
})
class MyComponent extends React.Component {
  render() {
    return <div>this component is lazyloaded by default!</div>;
  }
}

Special Tips

You should be aware that your component will only be mounted when it's visible in viewport, before that a placeholder will be rendered.

So you can safely send request in your component's componentDidMount without worrying about performance loss or add some pretty entering effects, see this demo for more detail.

Props

children

Type: Node Default: undefined

NOTICE Only one child is allowed to be passed.

scrollContainer

Type: String/DOM node Default: undefined

Pass a query selector string or DOM node. LazyLoad will attach to the window object's scroll events if no container is passed.

height

Type: Number/String Default: undefined

In the first round of render, LazyLoad will render a placeholder for your component if no placeholder is provided and measure if this component is visible. Set height properly will make LazyLoad calculate more precisely. The value can be number or string like '100%'. You can also use css to set the height of the placeholder instead of using height.

once

Type: Bool Default: false

Once the lazy loaded component is loaded, do not detect scroll/resize event anymore. Useful for images or simple components.

offset

Type: Number/Array(Number) Default: 0

Say if you want to preload a component even if it's 100px below the viewport (user have to scroll 100px more to see this component), you can set offset props to 100. On the other hand, if you want to delay loading a component even if it's top edge has already appeared at viewport, set offset to negative number.

Library supports horizontal lazy load out of the box. So when you provide this prop with number like 100 it will automatically set left edge offset to 100 and top edge to 100;

If you provide this prop with array like [100, 200], it will set left edge offset to 100 and top offset to 200.

scroll

Type: Bool Default: true

Listen and react to scroll event.

resize

Type: Bool Default: false

Respond to resize event, set it to true if you do need LazyLoad listen resize event.

NOTICE If you tend to support legacy IE, set this props carefully, refer to this question for further reading.

overflow

Type: Bool Default: false

If lazy loading components inside a overflow container, set this to true. Also make sure a position property other than static has been set to your overflow container.

demo

placeholder

Type: Any Default: undefined

Specify a placeholder for your lazy loaded component.

demo

If you provide your own placeholder, do remember add appropriate height or minHeight to your placeholder element for better lazyload performance.

unmountIfInvisible

Type: Bool Default: false

The lazy loaded component is unmounted and replaced by the placeholder when it is no longer visible in the viewport.

debounce/throttle

Type: Bool / Number Default: undefined

Lazyload will try to use passive event by default to improve scroll/resize event handler's performance. If you prefer control this behaviour by yourself, you can set debounce or throttle to enable built in delay feature.

If you provide a number, that will be how many ms to wait; if you provide true, the wait time defaults to 300ms.

NOTICE Set debounce / throttle to all lazy loaded components unanimously, if you don't, the first occurrence is respected.

demo

classNamePrefix

Type: String Default: lazyload

While rendering, Lazyload will add some elements to the component tree in addition to the wrapped component children.

The classNamePrefix prop allows the user to supply their own custom class prefix to help: # Avoid class conflicts on an implementing app # Allow easier custom styling

These being: # A wrapper div, which is present at all times (default )

style

Type: Object Default: undefined

Similar to classNamePrefix, the style prop allows users to pass custom CSS styles to wrapper div.

wheel

DEPRECATED NOTICE This props is not supported anymore, try set overflow for lazy loading in overflow containers.

Utility

forceCheck

It is available to manually trigger checking for elements in viewport. Helpful when LazyLoad components enter the viewport without resize or scroll events, e.g. when the components' container was hidden then become visible.

Import forceCheck:

import { forceCheck } from 'react-lazyload';

Then call the function:

forceCheck();

forceVisible

Forces the component to display regardless of whether the element is visible in the viewport.

import { forceVisible } from 'react-lazyload';

Then call the function:

forceVisible();

Scripts

$ npm run demo:watch
$ npm run build

Who should use it

Let's say there is a fixed date picker on the page, when user picks a different date, all components displaying data should send ajax requests with new date parameter to retreive updated data, even many of them aren't visible in viewport. This makes server load furious when there are too many requests in one time.

Using LazyLoad component will help ease this situation by only updating components visible in viewport.

Contributors

  1. lancehub
  2. doug-wade
  3. ameerthehacker

License

MIT

Comments
  • Doesn't render children in React 16.0

    Doesn't render children in React 16.0

    I have a component:

    <Lazyload once height={200}><Child/></Lazyload>

    This works in React 15.6.1, but not in React 16.0. The Child component's ComponentWillMount lifecycle method isn't being called. Neither is the render method.

    I tried making once=false, still doesn't work.

    opened by swarnakumar 22
  • forceCheck doesnt load items that are already in viewport

    forceCheck doesnt load items that are already in viewport

    Current implementation:

    /**
    *
    * CoverPhoto
    *
    */
    
    import React from 'react';
    import classnames from 'classnames/bind';
    import DebugHelper from 'utils/debug';
    import LazyLoad, { forceCheck } from 'react-lazyload';
    import styles from './CoverPhoto.styl';
    
    const cx = classnames.bind(styles);
    const debug = new DebugHelper('components/CoverPhoto');
    
    export class CoverPhoto extends React.Component {
      componentDidMount () {
        forceCheck();
      }
    
      render () {
    // const CoverPhoto = (props) => {
        debug('render');
        const { props } = this;
        const className = cx(props.className, {
          coverPhoto: true,
          hasRatio: props.ratio,
          [`ratio-${props.ratio}`]: props.ratio,
        });
        const imgProps = {
          src: props.src,
          alt: props.alt,
        };
    
        return (
          <div className={className}>
            <LazyLoad
              height={props.height || 100}
              offset={300}
              once
            >
              <img
                {...imgProps}
                className={styles.photo}
                role="presentation"
              />
            </LazyLoad>
          </div>
        );
      }
    }
    
    export default CoverPhoto;
    

    CoverPhoto is then used in other components, like a ProductCard:

    productcard

    Though forceCheck is called, the image is not loaded even though ProductCard is already inside the viewport.

    By looking at the log, somehow componentDidMount is being called before render(). Is that becuase the component is not fully mounted till LazyLoad finish rendering? Any hint on how this can be?

    opened by constantx 21
  • Placeholder component still visible

    Placeholder component still visible

    Hi,

    I am using the lazy load component and I have a problem on mobile where after scrolling the placeholders are not updated.

    I have the below overflows set in some of the top parents.

    overflow-x:hidden; overflow-y: auto;

    If I tap on the placeholder it updates and shows the element correctly.

    The LazyLoad component is as follows:

    <LazyLoad key={index} height={156} offset={156 * 3} placeholder={<ListItemPlaceholder/>} debounce={false} throttle={false} unmountIfInvisible={true} overflow={true} >

    Any advice?

    opened by simofacc 19
  • Testing with jest.

    Testing with jest.

    Any ideas how to test it shallow-ly with jest?

    I am trying to invoke scrollTo event on window, but that does not seems to have any effect.

    https://gist.github.com/jmacioszek/85fdd1b1eda9fe7f5f1664bd127af936

    results in:

    https://gist.github.com/jmacioszek/7c7c111e8e40477b897c1abcf26a0310

    Component defined as follows:

    https://gist.github.com/jmacioszek/aafd7650f36e80c7312c037622c89a64

    Appreciate any help, thanks.

    wontfix 
    opened by jmacioszek 18
  • [WARNING] findDOMNode is deprecated in StrictMode

    [WARNING] findDOMNode is deprecated in StrictMode

    I'm getting the following warning regarding the react-lazyload:

    Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of VisibilitySensor which is inside StrictMode. Instead, add a ref directly to the element you want to reference.

    Is there any idea about when it'll be resolved? I saw that there was already an issue related to it here but it was closed in 2019.

    opened by rafaelcamaram 16
  • parent.getAttribute is not a function error

    parent.getAttribute is not a function error

    After debugging this issue i have come to find that parent variable is being set to either Window or Document but neither of the two contain the getAttribute() function.

    This issue breaks my code and prevents the render of the component. I have defined my LazyLoad component as so..

        <div className={'Section6')}>
          <LazyLoad height={333} offset={300} overflow once>
            <Picture
              image={sectionImage}
              imageRetina={sectionImageRetina}
              imageMobile={sectionImageMobile}
              imageMobileRetina={sectionImage}
              screen={SCREEN_SIZES.SCREEN_SM_MAX} />
          </LazyLoad>
        </div>
    

    The parent div has a position: relative; styling

    Have I not used the overflow prop correctly? because it seems that although the overflow prop os set, the returned object in parent doesn't contain the function which needs to be checked for the condition and therefore breaks at this point and throws an error.

    alt text

    Have i missed something?

    opened by cnolimit 15
  • Briefly seeing previous image

    Briefly seeing previous image

    I submitted this on Stack Overflow as well.

    I am building a kind of searchable gallery site using React. It is being tested and continuously deployed at kitnic.it. The relevant source code is here.

    I am using react-lazyload to lazy load the thumbnail images. I tried a few other lazy load solutions, the only other one that worked was this simple one but the performance is a lot worse.

    The problem I am having is when I do a search the previous images in that place quickly pops up.

    I made a short demo video here: https://youtu.be/7Rnye3S0H-w

    To reproduce on kitnic.it:

    • scroll down
    • scroll up and search for 'uno'
    • scroll down again
    opened by kasbah 14
  • Overflow-x:hidden on html brakes lazy loading

    Overflow-x:hidden on html brakes lazy loading

    I ran into an issue where the <html> and <body> had overflow-x:hidden because of this slider menu plugin we are using, this was causing lazy load to break when scrolling vertically.

    Not sure if it is by design but I thought I'll mentioned here. It may also be related to #33

    opened by chrismadrigal 11
  • Not working (probably my mistake, though)

    Not working (probably my mistake, though)

    Hello, I'm trying to use this component inside of a custom Image component. It's quite simple, a stateless functional component. It looks as follows:

    import React, {PropTypes} from 'react';
    import classNames from 'classnames';
    import LazyLoad from 'react-lazyload';
    
    const Image = ({alt, className, lazyLoad, ...imgAttributes}) => {
        const classes = classNames(
            'Image',
            className
        );
        const img = <img alt={alt} className={classes} {...imgAttributes} />;
    
        if (lazyLoad) {
            return (
                <LazyLoad throttle={200} height={300}>
                    {img}
                </LazyLoad>
            );
        } else {
            return img;
        }
    };
    
    Image.propTypes = {
        className: PropTypes.string,
        /** Descriptive information about what is in the image. Do not use the words image, photo, or picture. */
        alt: PropTypes.string,
        lazyLoad: PropTypes.bool
    };
    
    Image.defaultProps = {
        className: '',
        alt: null,
        lazyLoad: false
    };
    
    export default Image;
    

    I then call it like this:

    <Image src="http://placehold.it/550x400" alt="Just a temporary placeholder" lazyLoad />
    

    I don't see the placeholder div and my image automatically gets rendered into the DOM without me scrolling to it (it's pretty far down). Even if I replace all of the logic for testing lazyLoad and displaying the correct thing, or remove it completely and just show the LazyLoad wrapped around an image, I still see the image rendered into the DOM automatically in the elements panel.

    Is there anything I'm doing wrong here?

    opened by reintroducing 10
  • Lazy Load working in overflow containers

    Lazy Load working in overflow containers

    Description

    I discovered that react-lazyloader doesn't check for visibility when the scroll event happens anywhere but the window (eg when the user scrolls inside of a div with overflow-y) This PR checks visibility on wheel events instead of on scroll, fixing the issue.

    Notable Changes

    Removes scroll prop Default behavior is use wheel, or fall back to mousewheel

    opened by mboperator 10
  • Add feature to have horizontal lazy-load

    Add feature to have horizontal lazy-load

    This PR will add a way to horizontally lazy-load items. This is useful for instance, when working with a carousel.

    Also, it fixes an error when using SSR frameworks like Next or react-tree-walker. They offer a way to unmount components on server, which causes react-lazyload to throw a lot of error since window is used in the componentWillUnmount.

    opened by ianwensink 9
  • #380 bugf: accept react 18 peer dep

    #380 bugf: accept react 18 peer dep

    this just bumps the peer deps and then it works

    npm i fails because of eslint packages. i removed them because id rather have a working production build than eslint tools.

    #380

    in the mean time i published a fork with this change on npm: https://www.npmjs.com/package/parm-react-lazyload

    this fork most likely will not be maintained. just a stop gap to keep my builds running until i come up with a long term solution

    opened by prmichaelsen 0
  • Build error: expected string or function, but got: object

    Build error: expected string or function, but got: object

    Hey,

    thank you for the great library which works great so far. We currently use it in an Astro Js environment within a react component, where it perfectly works in dev mode, but throws a build error like

    "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object."

    Typically, this is related to named/default exports and the corresponding import Synatx (see https://bobbyhadz.com/blog/react-element-type-is-invalid-expected-string-but-got), but this is not the solution here.

    Do you have any idea, what causes this error and how to fix it?

    Thanks in advance.

    Cheers, Christoph

    opened by christophberinger 1
  • REACT-LAZYLOAD PLACE HOLDER NOT RENDER

    REACT-LAZYLOAD PLACE HOLDER NOT RENDER

    Hi everyone,

    I am trying to use react-lazyload library to optimize performance, but i get an error that it keeps returning all the data for me(it doesn't show placeholder), not wait until I scroll down to render data, i did Tried many ways but still can't fix it, hope you guys can help me

    This is my code:

    image

    This is my DOM: image

    My react version:

    • react: 18.1.0
    • react-lazyload: ^3.2.0

    Thank you

    Trung

    opened by Trung229 2
Owner
twobin
twobin
An awesome Infinite Scroll component in react.

react-infinite-scroll-component A component to make all your infinite scrolling woes go away with just 4.15 kB! Pull Down to Refresh feature added. An

Ankeet Maini 2.2k Sep 24, 2022
react-sticky-scrollspy-nav is a React component that provides smooth scrolling navigation with sections to a web page.

react-sticky-scrollspy-nav react-sticky-scrollspy-nav is a React component that provides smooth scrolling navigation with sections to a web page. How

huurray 8 Aug 31, 2022
React component that scrolls to the top of a page when the current location gets changed

react-router-scroll-to-top ScrollToTop is a React component that scrolls to the top of a page when the current location gets changed. Since React Rout

Dima Zuien 0 Jan 11, 2022
Lazy load your component, image or anything matters the performance.

Note This project is now currently maintained by @ameerthehacker, please reach out to him on any issues or help. react-lazyload Lazyload your Componen

twobin 5.6k Sep 29, 2022
React-lazy-load - Lazy loading in react

React Lazy Load This project is created as part of below YouTube video.

Ashutosh Hathidara 32 Sep 7, 2022
Optimize nextjs performance by lazy load and hydrate under the fold

Lazy load and hydrate component on demand. Deal with Nextjs performance without compromise.

Thanh Le 34 Sep 30, 2022
Sentry - a developer-first error tracking and performance monitoring platform that helps developers see what actually matters, solve quicker, and learn continuously about their applications

Sentry is a developer-first error tracking and performance monitoring platform that helps developers see what actually matters, solve quicker, and learn continuously about their applications.

Sentry 32.1k Oct 1, 2022
⚡️The Fullstack React Framework — built on Next.js

⚡️The Fullstack React Framework — built on Next.js

⚡️Blitz 12.1k Sep 28, 2022
⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

⚡️Blitz 9.4k Oct 12, 2021
Lazy load & transition your React images with some WebGL glsl niceness 🎉

react-gl-transition-image ?? Lazy load & transition your React images with some WebGL glsl niceness ?? . Easy to use, offers 8 different transitions o

Jakob Stasilowicz 77 Aug 12, 2022
A Cross Platform(Android & iOS) ActionSheet with a flexible api, native performance and zero dependency code for react native. Create anything you want inside ActionSheet.

react-native-actions-sheet A highly customizable cross platform ActionSheet for react native. Screenshots Features Cross Platform (iOS and Android) Na

Ammar Ahmed 925 Sep 23, 2022
React Redux Multi-Step Signup Form. Created with React, Redux Toolkit, and SASS. Plus React Lazy Load for Component loading.

React Redux Multi-Step Signup Form. Created with React, Redux Toolkit, and SASS. Plus React Lazy Load for Component loading.

Rishi Singh Bhachu 15 Sep 19, 2022
React Component to lazy load images and components using a HOC to track window scroll position.

React Component to lazy load images and other components/elements. Supports IntersectionObserver and includes a HOC to track window scroll position to improve performance.

Albert Juhé Lluveras 1k Sep 24, 2022
🌅 React lazy load images with IntersectionObserver API and Priority Hints

React Simple Img Smart react lazy load image with IntersectionObserver API, Priority Hints and animations Features Speed up initial page loads by load

Bill 979 Sep 5, 2022
React Image and Background Image Preloader and Fade in. Load those images in smooth!

React Image and Background Image Fade Fade in images AND background images easily in React ?? ! Demo and Docs are live! react-image-and-background-ima

Nick Porter 27 Aug 11, 2022
Check your device when you have anything to change on your PC or mobile

Check your device when you have anything to change on your PC or mobile.

ChoGeonHo 11 Aug 6, 2022
Here is the place try to learn to call API using React.js with anything your code style and contribute to open-source. Part of Hacktoberfest

Table of Contents About The Project Built With Getting Started Prerequisites Installation Usage About The Project To welcome hacktoberfest we provide

Abdul Hakim 12 Jul 17, 2022
Tiny (2.3kB) React component for image lazy loading

React Pics Tiny (2.3kB) React component for image lazy loading Demo Table of Contents React Pics Table of Contents Installation Usage Basic With a pla

medipass 32 Dec 26, 2021
A React Native component for user to draw anything by touching screen

react-native-drawpad Basic useful feature list: Let users draw anything they want! change color of input easily change thickness of input easily defau

Partido 用遊戲聊天交友 30 Feb 21, 2022
Lightbox image image viewer for react with zoom, rotate and move feature with single or multi image 💡📦

Lightbox for react with zoom, rotate and move feature with touch support ????

Anam Ahmed 134 Aug 24, 2022