前端开发 / React 懒加载组件 react-lazy-load-image-component

本文详细介绍如何在 React 项目中, 使用 react-lazy-load-image-component 组件来实现图片懒加载功能,从安装、使用到常见问题,帮助你快速、简单、高效的添加懒加载功能。

前端开发 / React 懒加载组件 react-lazy-load-image-component

Lazy Loading 懒加载介绍

什么是 Lazy Loading 懒加载

Lazy Loading ,也叫延迟加载,是一种性能优化技术,用于优化内容的加载时间。

这种技术允许你按需加载内容,而不是在页面首次加载时加载所有内容。这样,用户可以更快地看到并与页面交互,而不需要等待所有内容都加载完毕。

lazyloading-in-react20230826

Lazy Loading 的优点

在 Web 开发中, Lazy Loading 最常用于图片和视频资源:网页上的图片和视频往往占用了大部分的带宽。通过 lazy loading ,你可以在用户滚动到图片或视频位置时才加载它们,而不是在页面加载时立即加载所有资源。

Lazy Loading 的优点:

  • 提高首次页面加载速度:用户不需要等待所有内容都加载完毕就可以开始与页面交互。
  • 节省带宽:只有用户实际查看或需要的资源才会被下载。
  • 减少服务器负载:服务器只需要为实际请求的资源提供服务,而不是为每个访问者提供所有资源。

Lazy Loading 懒加载技术相关组件

现在有很多非常优秀的 Lazy Loading 实现的工具/库,其中专门为 React 或 Next.js 设计的:

工具/库核心特点主要劣
next/image 👍– Next.js 内置
– 支持自动优化和响应式设计
– 限制于 Next.js 项目
react-lazyload– 简单易用
– 事件驱动的延迟加载
– 可能需要额外的配置和样式调整
react-lazy-load-image-component– 支持占位符
– 支持图片和背景
– 不如其他库灵活

如果你是 Next.js 开发的项目,我强烈推荐你使用 Image 组件来实现懒加载,我在这篇文章中进行了详细的介绍。

这篇文章,我将介绍 react-lazy-load-image-component 这个组件。

react-lazy-load-image-component 组件使用方法

组件介绍

react-lazy-load-image-component 是一个 专为 React 开发的库,其主要目标是提供图片和背景图片的懒加载功能。这个库对于优化网站或应用的性能特别有用,因为它能够延迟加载视口外的图像,从而减少不必要的网络请求,提高页面的加载速度。

react-lazy-load-image-component 的一些核心特点:

  1. 图片懒加载:只有当图片进入或即将进入视口时,图片才会被加载。这样可以确保用户只加载他们真正需要看到的图片。
  2. 背景图片懒加载:不仅可以懒加载<img>标签,还可以懒加载背景图片。
  3. 模糊效果:在图片加载之前,可以选择显示一个模糊的低分辨率图像作为占位符。
  4. 服务器端渲染(SSR) 兼容:这个库设计得与服务器端渲染完全兼容。
  5. 自定义占位符:在图像加载时,您可以显示自定义的占位符。
官方地址: https://github.com/Aljullu/react-lazy-load-image-component

组件效果

可以在这里查看官方演示效果:

https://www.albertjuhe.com/react-lazy-load-image-component/

组件安装

使用 npm 安装:

npm i --save react-lazy-load-image-component

使用 yarn 安装:

yarn add react-lazy-load-image-component

基础使用语法

LazyLoadImage 组件使用方法和 HTML 中的 img 标签非常相似:

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

function MyComponent() {
  return (
    <LazyLoadImage
      alt="example-image"
      height={400}
      src="path-to-your-image.webp" // use normal <img> attributes as props
      width={400} />
  );
}

在这个示例中,只有当图片进入视口时,path-to-your-image.webp 才会被加载。

添加占位符效果

LazyLoadImage 组件内置了多种可选的占位符效果:

  • blur :基于 placeholderSrc 渲染模糊图像,并在加载 src 中指定的图像时转换为非模糊图像。
  • black-and-white :基于 placeholderSrc 渲染黑白图像,并在加载 src 中指定的图像时转换为彩色图像。
  • opacity :渲染空白区域并在加载图像时过渡到完全不透明。

注意:以上效果都依赖于格外的 css 文件。

例如,如果要实现 blur 效果:

import React from 'react';
import { LazyLoadImage } from 'react-lazy-load-image-component';
import 'react-lazy-load-image-component/src/effects/blur.css';

const MyImage = ({ image }) => (
  <LazyLoadImage
    alt={image.alt}
    effect="blur"
    src={image.src} />
);
image-20230827210354068

为图片添加 height 和 width 参数

为什么建议使用这两个参数?

有时候你可能会遇到:懒加载无法正常功能,而是一次加载所有图像。

这是因为:当图像在视口中可见时,此包会加载图像。在加载图像之前,它占用 0x0 像素,因此如果您有一个图像库,这意味着所有图像都将位于页面的可见部分,直到第一个图像加载并开始下推其他图像。

为了避免出现这个问题,就需要为图片设置 height 和 width 属性。

<LazyLoadImage
  key={image.key}
  src={image.src}
  alt={image.alt}
  height={image.height}
  width={image.width} />

一般 width 和 height 在后端 API 提供图片 URL 时,一并提供。

比如,如果你后端服务使用 FastAPI 来实现,那么你可以使用 Pillow 来获取图片文件的高、宽像素,并提供给前端。

就像这样:

def image_to_pixel(image_path: str) -> Tuple[int, int]:
    with Image.open(image_path) as img:
        width, height = img.size

    return width, height

使用 trackWindowScroll 优化加载性能

当在同一页面中有大量元素需要延迟加载时,性能可能会受到影响,因为每个元素都会监听滚动和调整大小的事件。例如,你要使用一个图库网站,可能有大量的图片需要还在显示,此时网站性能会明显下降。

可以使用 react-lazy-load-image-component 内置的 trackWindowScroll 方法来解决这个问题。

trackWindowScroll 原理

如果你有很多图片希望在适当的时候显示(懒加载),而不是让每张图片都自己去判断是否应该显示,那效果会很慢。

trackWindowScroll 就像一个观察员,当你在网页上滚动或改变窗口大小时,它会注意到这些变化。它会告诉这些图片:“现在是你显示的时候了”,这样整个页面就会运行得更快、更顺畅。

trackWindowScroll 的详细工作原理如下:

  1. 事件监听: 当首次有一个组件使用 trackWindowScroll 时,它会给窗口添加滚动和大小调整事件的监听器。
  2. 事件共享: 而不是每个懒加载组件都单独监听滚动和窗口大小调整事件,trackWindowScroll 允许多个组件共享相同的事件。这减少了重复的事件监听器,从而提高性能。
  3. 提供位置信息: 当滚动或窗口大小发生变化时,trackWindowScroll 会捕获相关的位置信息(如滚动位置)并传递给它所包裹的子组件。
  4. 移除事件监听器: 当所有使用 trackWindowScroll 的组件都已卸载,它会从窗口中移除事件监听器,避免不必要的内存占用。
  5. 优化性能: 由于只有一个共享的事件监听器,当页面上有多个懒加载组件时,性能会得到明显优化。这避免了大量的事件监听器可能对性能造成的负面影响。

使用方法

简单使用示例:

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

class YourComponent extends React.Component {
    render() {
        // 使用 this.props.scrollPosition 提供给 LazyLoadImage 或 LazyLoadComponent
        return <LazyLoadImage src="your_image_url.webp" scrollPosition={this.props.scrollPosition} />;
    }
}

export default trackWindowScroll(YourComponent);

在导出组件时,使用 trackWindowScroll 包装组件。

在你的组件内,确保将 scrollPosition 属性传递给 LazyLoadImage 或 LazyLoadComponent。这样,它们就可以利用 trackWindowScroll 提供的共享监听器。

例如,如果我们有一个 App 来渲染 Gallery ,我们将用 HOC 包装 Gallery 组件:

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

const Gallery = ({ images, scrollPosition }) => (
  <div>
    {images.map((image) =>
      <LazyLoadImage
        key={image.key}
        alt={image.alt}
        height={image.height}
        // Make sure to pass down the scrollPosition,
        // this will be used by the component to know
        // whether it must track the scroll position or not
        scrollPosition={scrollPosition}
        src={image.src}
        width={image.width} />
    )}
  </div>
);
// Wrap Gallery with trackWindowScroll HOC so it receives
// a scrollPosition prop to pass down to the images
export default trackWindowScroll(Gallery);