两者的关系
原来一直以为 code splitting 了,就已经实现了懒加载了,但现在 react 又单独退出了懒加载功能,突然就迷茫了,webpack 已经实现懒加载了,为什么 react 还要单独实现这个功能呢?细心思考才明白两者之间的关系。
code splitting 实现了代码分割,就是不把所有的代码打包到一起,这只是解决了单个大文件加载慢的问题(因为浏览器现在可以同时多个线程下载文件),而不是懒加载的问题。
什么是懒加载?
懒加载就是没用到某个文件的时候,这文件不下载,用到的时候才下载加载,从而提高性能。
注意:懒加载时,如果文件没用到,连下载都不下载,而不是下载下来不加载。
而要实现懒加载,那首先各个文件是分开的,这就依赖 code splitting 功能,不然代码都在一个文件里,动态加载个屁。
react 懒加载
react 的懒加载,提供了 lazy 和 suspense,另外需要借助 js 的 import()“函数”(其实本质不是个函数
)。
懒加载解决了页面首次加载的性能问题。
lazy
lazy 接收一个无参的函数,返回一个新的 react 组件
1 | import React,{lazy} from 'react; |
可以指定动态加载 chunk 的名字,通过在 import 里面加注释实现。
1 | const About = lazy(() => import(/* webpackChunkName:"about" */ "./About")); |
这在浏览器的 network 中,就可以看到 About 组件的 chunk 文件名叫about.chunk.js
,如果不指定,则是 0.chunk.js 这样,用数字命名。
注意
webpackChunkName:"about"
两边要有空格,如果没有空格,也不报错,只是 chunk 文件中的代码以文本的方式显示,所有代码都是黑色的。带空格就会以代码的格式,字体有颜色。
另外注意 value 上的双引号。
Suspense
使用lazy
必须使用Suspense
组件,Suspense
是react
的一个内置组件。
suspense 是干什么的,因为 lazy 是动态加载,所以加载过程中会有一个空档期,Suspense 就是执行,这个空档期显示什么。
Suspense 的 fallback 属性执行了要显示的组件,fallback 接收的是一个组件的实例,而不是组件的类型(感觉一句废话)。
1 | import React, { Component, lazy, Suspense } from "react"; |
错误处理
如果组件下载失败,会报错,Suspense 没有处理错误的能力。那错误如何处理呢?使用 ErrorBoundary(错误边界),其实就是利用了组件的componentDidCatch
生命周期。
当 UI 渲染有错误时,就会触发 getDerivedStateFromError 和 componentDidCatch,可以在设置 state 的状态,然后根据 state 判断是否显示错误组件。
1 | import React, { Component, lazy, Suspense } from "react"; |
也可以使用getDerivedStateFromError
返回一个新的 state 对象并合并到原来的 state 中。
1 | static getDerivedStateFromError(error, info) { |
官方建议:当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。
错误边界的介绍