为什么react要使用lazy进行懒加载

380 阅读2分钟

最近公司重构了之前的老项目(react16.13.1),新项目用到了webpack出的微前端以及react18,在引用远程项目的时候就会用到lazy,使用时一定要记得配合Suspense食用。一直觉得很麻烦,后边才发现真香,比起老项目运行真的是体验嘎嘎好。

使用目的

懒加载组件,减少了首次访问的速度,体验提升;减少了白屏等待时间,白屏有很多原因,解决浏览器缓存当然是更好的,这里指路浏览器缓存机制

原理

React利用 React.lazy 与 import() 实现了渲染时的动态加载 ,并利用 Suspense 来处理异步加载资源时页面应该如何显示的问题

代码分割

前端利用工具打包时会产生产生一个 bundle.js 文件,而随着我们引用的第三方库越来越多或业务逻辑代码越来越复杂,bundle.js 文件体积就会越来越大,首屏加载就会花费更多。因此需要利用技术手段来对包进行分割,比如本文讲到利用webpack的手段。

import原理

import() 函数是由TS39提出的一种动态加载模块的规范实现,其返回是一个 promise。当 Webpack 解析到该 import() 语法时,会自动进行代码分割

React.lazy 原理

在react16.8.0 版本增加的新特性。React.lazy() 所返回的 LazyComponent 对象,其 _status 默认是 -1,所以 首次渲染 时,会进入 readLazyComponentType 函数中的 default 的逻辑,这里才会真正异步执行 import(url) 操作,由于并未等待,随后会检查模块是否 Resolved,如果已经Resolved了(已经加载完毕)则直接返回 moduleObject.default (动态加载的模块的默认导出),否则将通过 throw 将 thenable 抛出到上层

Suspense 原理

React 捕获到异常之后,会判断异常是不是一个 thenable,如果是则会找到 SuspenseComponent ,如果 thenable 处于 pending 状态,则会将其 children 都渲染成 fallback 的值,一旦 thenable 被 resolve 则 SuspenseComponent 的子组件会重新渲染一次

使用方法

import React, { Suspense } from "react";

const HomePage = React.lazy(() => import("./pages/HomePage"));

使用场景

其实对于单页面,以及小的网站来说,使用懒加载也不是必选项。但是对于大型项目,尤其是有很多模块构建的项目,用懒加载对于性能和体验会有显著的提升