React拆分组件的最佳实践?

2022-04-28  本文已影响0人  莫帆海氵

目前常用的做法使用 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. 非重要内容(1信息不重要、2不会影响 layout 造成重绘)
  3. 对比页面来说是重的组件,比如占用资源达到页面的一部分(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>
    )
  }
}
...

结果截图


第一次仅渲染 Header 组件 等待 GoodsBody 资源加载后渲染 接着等待 GuidePopup 资源加载后渲染 最后是 RuleButton 组件 当因为父组件状态更新,三个 Suspense 都重新渲染

推荐每个组件都是用单独的 Suspense 包裹,可以单独渲染,如果多个组件使用一个 Suspense,其下面的所有组件是同时渲染,如果子组件没做好状态控制容易造成多次渲染。

一个 Suspense 下面的多个组件都会同时渲染
上一篇 下一篇

猜你喜欢

热点阅读