LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

React 懒加载:让组件 “躺平” 到要用时再干活

zhenglin
2026年2月2日 8:56 本文热度 64

前言

之前咱们聊了普通网页的图片懒加载 —— 让图片 “藏” 在屏幕外摸鱼,滚到眼前再开工。那 React 项目里的组件和图片呢?总不能一打开页面就把所有组件的代码都拽过来吧?

想象下:你打开购物App页面,首页就加载了 “订单页”“个人中心” 的代码,结果用户根本没点进去 —— 这不是纯纯的浪费流量和性能吗?React 的懒加载,就是给组件和图片发 “摸鱼许可证”没出现在视野里,就别加载,躺平到要用时再干活


一、React 里的 “组件懒加载”:React.lazy + 动态导入

我们先创建一个Demo组件,并看这行代码:

// 别直接import Demo,改成动态导入 

const Demo = lazy(() => import('./Demo'));

这行代码的魔力在于:

  • 原本import Demo from './Demo'会在页面初始化时就加载 Demo 组件的代码

  • React.lazy+import()包裹后,Demo 的代码会被单独打包成一个小文件,只有当 Demo 组件要被渲染(比如滚到可视区域)时,这个小文件才会被下载、加载。


搭配Suspense(不然组件加载时会 “崩”)

不过光用lazy还不够 —— 组件加载需要时间,加载过程中页面会报错。得用Suspense当 “占位符”:


import { lazy, Suspense } from 'react';

const Demo = lazy(() => import('./Demo'));


export default function App() {

    return (

        <div>

            {/* 一堆内容... */}

            <Suspense fallback={<div>组件加载中...</div>}>

                <Demo />

            </Suspense>

        </div>

    );

}

fallback里写的就是组件加载时的 “Loading 占位”,比如转圈圈、提示文字,用户体验会更友好。



二、React 里的 “图片 / 内容懒加载”:react-lazyload 或 自定义组件

组件懒加载管的是 “代码包”,图片 / 内容懒加载管的是 “可视区域内才渲染内容”。我常用的有两种方案:


方案 1:直接用react-lazyload库(现成的轮子)

仓库地址: www.npmjs.com/package/rea…

下载方法:npm i react-lazyload


导入的LazyLoad就是这个库,直接包在图片外面:

import LazyLoad from 'react-lazyload';


// 在App.jsx里用:

<LazyLoad placeholder={<div>图片加载中...</div>} offset={300}>

    <img src="https://xxx.png" alt="" />

</LazyLoad>

  • placeholder:图片加载前的占位内容;

  • offset={300}提前 300px 开始加载图片(用户还没滚到,图片已经在偷偷加载了,体验更丝滑)。


完整代码(为了更好展现效果,我放了50个p标签):

代码高亮:

import LazyLoad from 'react-lazyload';

import { lazy } from 'react'

// import Demo from './Demo'

import MyLazyLoad from './MyLazyLoad'


// 组件没有出现在可视区域时,组件代码都不会被加载,被import('./Demo')包裹的模块会单独打包

const Demo = lazy(() => import('./Demo'));


export default function App() {

    return (

        <div>

            {/* <Demo></Demo> */}

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <p>xxx</p>

            <MyLazyLoad placeholder={<div>loading...</div>} width='100px' onContentVisible={() => console.log('onContentVisible')} onClose={() => console.log('onClose')}>

                {/* <img src="https://inews.gtimg.com/om_bt/OG4Cnt2SgXAuTj-Vv77ASGszUj1BwOhUXtBCplSlBfQmAAA/641" alt="" /> */}

                <Demo></Demo>

            </MyLazyLoad>

            <LazyLoad placeholder={<div>loading...</div>} offset={300}>

                <img src="https://inews.gtimg.com/om_bt/Os3eJ8u3SgB3Kd-zrRRhgfR5hUvdwcVPKUTNO6O7sZfUwAA/641" alt="" />

            </LazyLoad>

        </div>

    )

}

可以看到最开始的界面显示的都是loading


我们慢慢往下滑:

 


滑到Demo和 照片


方案 2:自己写一个懒加载组件(比如我自己写的MyLazyLoad.jsx

我写的MyLazyLoad组件,核心就是用IntersectionObserver实现 “可视区域检测”,逻辑和之前普通网页的懒加载是通的:

 

// MyLazyLoad.jsx核心代码

import { useState, useRef, useEffect } from 'react';


export default function MyLazyLoad(props) {

    const { placeholder, children, offset, onContentVisible } = props;

    const [visible, setVisible] = useState(false);

    const containerRef = useRef(null);

    const elementObserver = useRef();


    // 初始化IntersectionObserver

    useEffect(() => {

        const options = {

            threshold: 0,

            rootMargin: typeof offset === 'number' ? `${offset}px` : '0px'

        };

        // 监听元素是否进入可视区域

        elementObserver.current = new IntersectionObserver(lazyLoadHandler, options);

        const node = containerRef.current;

        elementObserver.current.observe(node);


        // 卸载时停止监听

        return () => {

            elementObserver.current.unobserve(node);

        };

    }, []);


    // 元素进入可视区域后的处理

    function lazyLoadHandler(entries) {

        const [entry] = entries;

        if (entry.isIntersecting) {

            setVisible(true); // 显示真实内容

            onContentVisible?.(); // 触发“内容可见”的回调

            elementObserver.current.unobserve(containerRef.current); // 停止监听

        }

    }


    // 没进入可视区域就显示占位,进入了就显示真实内容

    return (

        <div ref={containerRef}>

            {visible ? children : placeholder}

        </div>

    );

}

用的时候和react-lazyload差不多,把要懒加载的内容包进去:

<MyLazyLoad placeholder={<div>加载中...</div>} offset={300}>

    <img src="https://xxx.png" alt="" />

    {/* 甚至可以包组件:<Demo /> */}

</MyLazyLoad>


三、“组件懒加载”+“内容懒加载”:双剑合璧

把前面的技术结合起来,就是 React 项目里的 “终极懒加载”

 

import { lazy, Suspense } from 'react';

import MyLazyLoad from './MyLazyLoad';


// 组件代码懒加载

const Demo = lazy(() => import('./Demo'));

export default function App() {

    return (

        <div>

            {/* 一堆内容... */}

            {/* 组件代码+组件内容 都懒加载 */}

            <Suspense fallback={<div>组件包加载中...</div>}>

                <MyLazyLoad placeholder={<div>组件内容加载中...</div>}>

                    <Demo />

                </MyLazyLoad>

            </Suspense>

        </div>

    );

}

  • 第一步:用户滑到 Demo 区域前Demo的代码包不会下载

  • 第二步:代码包下载完成后,MyLazyLoad会等 Demo 进入可视区域,再渲染 Demo 的内容;

  • 全程都有占位提示,用户不会看到 “空白” 或 “报错”


四、总结

  • React 懒加载分两类React.lazy+Suspense实现组件代码按需下载react-lazyload/ 自定义组件实现内容按需渲染

  • 核心价值:减少初始化资源开销,提升页面加载和渲染性能。


结语

普通网页的懒加载是让图片 “摸鱼”React 的懒加载则是给组件和代码都发了 “摸鱼许可证”—— 不用一开场就全员到岗,该躺平时躺平,该干活时再发力。

就好比经营一家店,不用把所有商品都堆在门口 (初始化加载所有代码),而是把暂时没人要的商品放进仓库 (单独打包组件),等顾客问到了再取出来,摆上货架(渲染内容)—— 既省了门口的空间 (页面加载性能),又不会让顾客等太久 (优化用户体验)


参考文章:原文链接


该文章在 2026/2/2 8:56:20 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved