目前常用的做法使用 React 的 lazy 和 suspence 在组件维度实现拆分资源包。
lazy + Suspence
import React, { lazy, Suspense } from "react"
const Header = lazy(() => import("./components/Header"))
const MyHi = () => {
return(
...
<Suspense fallback={null}>
<Header />
</Suspense>
...
)
}
为什么拆分组件?
减少请求资源的大小,让首屏能更快渲染
从上图能看到 activity_full_refund_new 的资源拆分后减少 6KB,新增三个独立资源 0、1、2
拆分的标准
简单的做法就是每个组件都拆分,这样拆分问题,如果每个组件都拆分会有许多琐碎的资源,首次渲染的时间可能很快,但界面依然是空白的,还是需要等待组件的资源加载完成才能看到组件的,所以需要区分一下哪些组件可以拆分?
可以拆分的组件标准:
- 首屏不会加载的
- 非重要内容(1信息不重要、2不会影响 layout 造成重绘)
- 对比页面来说是重的组件,比如占用资源达到页面的一部分(25%?)
示例
import React, { lazy, Suspense } from "react"
import ReactDOM from "react-dom"
// 首屏组件
import Header from "./components/Header"
// 重组件
const GoodsBody = lazy(() => import("./components/GoodsBody"))
// 非重要组件
const GuidePopup = lazy(() => import("./components/GuidePopup"))
// 非重要组件
const RuleButton = lazy(() => import("components/RuleButton"))
...
render() {
let {
remaining_times,
} = this.state
return (
<div className="container">
<Header remainingTimes={remaining_times} />
<Suspense fallback={null}>
<GoodsBody
goodsList={goods_list}
/>
</Suspense>
<Suspense fallback={null}>
<GuidePopup />
</Suspense>
<Suspense fallback={null}>
<RuleButton backgroundColor="#d35c3b" />
</Suspense>
</div>
)
}
}
...
结果截图
推荐每个组件都是用单独的 Suspense 包裹,可以单独渲染,如果多个组件使用一个 Suspense,其下面的所有组件是同时渲染,如果子组件没做好状态控制容易造成多次渲染。