懒加载
React 中懒加载是一种按需加载组件的机制,有些组件不需要在页面初始化就进行加载,这些组件可以按需加载,当需要时再进行加载。懒加载是怎么实现的呢?如果要实现一个懒加载功能应该怎么去做呢?可以通过异步动态加载组件 import()
进行实现,把组件理解为远程数据,去网络下载组件,下载完成之后通知页面并进行渲染 。同时将懒加载组件作为Suspense的子组件,没有渲染完成时显示“加载中…”。
实现懒加载
简单的实现一个 lazy 方法,传入 ()=>import(‘./Component.js’),首次渲染时进行加载。
function lazy(load) {
const moduleLoader = createModuleLoader(load);
return function (props) {
const Component = moduleLoader.loadModule();
return <Component {...props} />;
};
}
const createModuleLoader = (load) => {
return {
module: null,
promise: null,
loadModule() {
//已加载直接返回
if (this.module != null) {
return this.module
}
if (this.promise == null) {
this.promise = load().then(
(res) => {
this.module = res.default;
},
(error) => {
this.error = error;
}
);
}
},
};
};
React中懒加载的实现
首先创建 React 懒加载代码
export default function App() {
//懒加载 List 组件
const AList = lazy(()=>import('./List.js'))
const r = useRef(null)
const [show, setShow] = useState(false);
return (
<>
<button onClick={()=>{
setShow(!show)
console.log("asdf")
}} >加载组件</button>
{show ?
<Suspense fallback="loading">
<AList items={[{id:1, text:"123"}]}>asdf</AList>
</Suspense>
:""}
</>
);
}
- 由以下代码可以看出,lazy 返回了 elementType,值为REACT_LAZY_TYPE
- Lazy 懒加载的组件在以下代码中初始化
- 可以看到 ctor 是我们传入 import 代码
- 返回 pending 状态,此时显示加载中
- 组件加载成功,可以正常显示。
lazy 对应的 elementType
懒加载在 React 中是一个特别 elementType,下图中是React 定义的 ElementType
从 Lazy Element 创建 Lazy Fiber,fiberTag 为 LazyComponent
绑定并渲染 Fiber lazyComponent
更新组件
总结
React 懒加载底层原理是动态引入,由于需要构建 Fiber,React 需要将 lazyComponent 转为 Fiber 节点并最终进行渲染。