欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React渲染的優(yōu)化方案

 更新時(shí)間:2024年08月14日 08:48:11   作者:brandonxiang  
react的渲染機(jī)制是非常獨(dú)特的,有別于 Vue 框架的渲染次數(shù)的優(yōu)化計(jì)算,React 很久以來就有PureComponent、shouldUpdate,本文小編給大家介紹了React渲染的優(yōu)化方案,需要的朋友可以參考下

一、引子

react的渲染機(jī)制是非常獨(dú)特的,有別于 Vue 框架的渲染次數(shù)的優(yōu)化計(jì)算。React 很久以來就有PureComponent、shouldUpdate。Function component 又有了memo、useMemo、useCallback 這樣的函數(shù)工具,讓它成為有一定深度的前端框架。

怎么使用 useMemo 和 useCallback 是我們值得思考的點(diǎn)。

二、代碼范式

首先,假設(shè)大家對 React 都有一個(gè)基礎(chǔ)的入門水平,所以本文不再贅述“useMemo 和 useCallback ”基本用法。

2.1 Memo 緩存組件

引起重渲染的最常見的情況是,組件的 props。memo包裹著函數(shù)組件,針對props 參數(shù)的淺對比。

子組件的渲染有些情況,子組件控制不住,它受到父組件的參數(shù)影響。

function _Boxes({ boxes }: {
  boxes: {
    flex: number;
    background: string;
  }[]
}) {
  return (
    <div className="boxes-wrapper">
      {boxes.map((boxStyles, index) => (
        <div className="box" style={boxStyles} key={index} />
      ))}
    </div>
  );
}

const Boxes = memo(_Boxes);

2.2 父組件層面,對象使用 useMemo

作為 Box 的父組件,boxes 的傳參是一個(gè)對象,每次改變,它會生成一個(gè)全新的對象。這里要對 boxes 對象使用緩存(useMemo)。這樣,age 的改動(dòng)將不會影響到 Box 的重渲染。

function App() {
  const [age, setAge] = React.useState(0);
  const [boxWidth, setBoxWidth] = React.useState(1);

  const id = React.useId();

  // Age 屬性的變更不會影響 boxes 屬性變化
  const boxes = useMemo(() => {
    return [
      { flex: boxWidth, background: 'hsl(345deg 100% 50%)' },
      { flex: 3, background: 'hsl(260deg 100% 40%)' },
      { flex: 1, background: 'hsl(50deg 100% 60%)' },
    ];
  }, [boxWidth]);

  return (
    <>
      <Boxes boxes={boxes} />

      <section>
        <button onClick={() => {
          setAge(age + 1)
        }}>
          Increment age
        </button>
        <p>Hello! You are {age}.</p>
      </section>

      <section>
        <label htmlFor={`${id}-box-width`}>
          First box width:
        </label>
        <input
          id={`${id}-box-width`}
          type="range"
          min={1}
          max={5}
          step={0.01}
          value={boxWidth}
          onChange={(event) => {
            setBoxWidth(Number(event.target.value));
          }}
        />
      </section>
    </>
  );
}

2.3 context provider 最好用 useMemo

同理,參考《How To useContext With useReducer》,context provider 的 value 參數(shù)是一個(gè)很容易被遺忘的點(diǎn),provider 可能會傳入一個(gè)對象,利用useMemo 或者 useCallback 來保護(hù) App 組件不會做出過多重渲染。

const Main = () => {
  const [state, dispatch] = useReducer(reducer, { age: 42 });
  
  // 利用useMemo 或者 useCallback 來保護(hù) Context 不會做出過多重渲染
  const contextValue = useMemo(() => {
    return { state, dispatch };
  }, [state, dispatch]);
  
  return (
    <MyContext.Provider value={contextValue}>
      <App />
    </MyContext.Provider>
  )
}

2.4 其他

還有一種特殊情況是:不規(guī)范、分批的 Context 調(diào)用導(dǎo)致了頁面的重新渲染。針對一些老舊項(xiàng)目,以前的業(yè)務(wù)邏輯導(dǎo)致 Context 的調(diào)用混亂,已經(jīng)不是前面幾種方法能夠解決的。

解決方法:改動(dòng)代碼,把多次 Context 調(diào)用整合為一次。

三、補(bǔ)救防范

3.1 斷點(diǎn)查看調(diào)用堆棧

利用 Chrome 原生調(diào)試工具打斷點(diǎn),看每一行代碼的堆棧信息。這種方式最為原始但是它往往“行之有效”。

3.2 devtool 查看渲染次數(shù)和渲染堆棧

React Devtool 的 Profiler 能協(xié)助我們排查 React 渲染次數(shù)和渲染堆棧。

  • 點(diǎn)擊 Profiler 的記錄圓圈
  • 刷新頁面或者做其他操作
  • 停止記錄
  • 參考快照記錄

同時(shí),我們還能夠通過“highlight updates when components render”來可視化整個(gè)渲染過程。

3.3 渲染打印工具

ahooks的useWhyDidYouUpdate

該函數(shù)能夠幫助開發(fā)者排查是哪個(gè)屬性改變導(dǎo)致了組件的 rerender,但是更多集中在 props、state,開發(fā)者需要主動(dòng)去縮小范圍,它起到輔助打印的工作,如果是 Context 或者更外側(cè)的數(shù)據(jù)變動(dòng),效果不見得達(dá)到效果。

Welldone Software 的 why-did-you-render

該工具能全局打印 rerender 日志,但是在復(fù)雜項(xiàng)目當(dāng)中,它的打印較為混亂,不一定能夠很好的發(fā)現(xiàn)問題。

四、總結(jié)

React 的渲染優(yōu)化有非常多篇博客已經(jīng)聊過,但是還是“No Silver Bullet”,沒有最佳方案。特別在一些數(shù)據(jù)流非常復(fù)雜的前端工程項(xiàng)目當(dāng)中。

React 的前端項(xiàng)目能夠劃分為:聰明組件和懶惰組件。聰明組件負(fù)責(zé)的內(nèi)容是頁面邏輯的數(shù)據(jù)流向,懶惰組件負(fù)責(zé)的是樣式的渲染,數(shù)據(jù)流越是清晰,代碼可維護(hù)性越強(qiáng)。

以下是我個(gè)人的代碼編寫建議:

  • 不要把所有數(shù)據(jù)都往 Context 里面放,只有極其核心,多個(gè)頁面都復(fù)用情況。
  • 簡單的頁面,盡量以聰明組件和懶惰組件的方式來處理。
  • 如果已經(jīng)出現(xiàn)數(shù)據(jù)流混亂的情況下,合理使用 memo,或者狀態(tài)管理工具(例如zustand、jotai等)讓代碼數(shù)據(jù)流盡量走向清晰,初始化主路徑盡量批量渲染好。

雖然有很多分析工具,但是它們更多是輔助,最重要還是要通過人工分析。重點(diǎn)要分析出渲染次數(shù)過多的代碼,做出針對性地處理。

以上就是React渲染的優(yōu)化方案的詳細(xì)內(nèi)容,更多關(guān)于React渲染優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React中setState/useState的使用方法詳細(xì)介紹

    React中setState/useState的使用方法詳細(xì)介紹

    這篇文章主要介紹了React中setState/useState的使用方法,useState 和 setState 在React開發(fā)過程中 使用很頻繁,但很多人都停留在簡單的使用階段,并沒有正在了解它們的執(zhí)行機(jī)制
    2023-04-04
  • Native?Memory?Tracking追蹤區(qū)域示例分析

    Native?Memory?Tracking追蹤區(qū)域示例分析

    這篇文章主要為大家介紹了Native?Memory?Tracking追蹤區(qū)域示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • antd?3.x?Table組件如何快速實(shí)現(xiàn)虛擬列表詳析

    antd?3.x?Table組件如何快速實(shí)現(xiàn)虛擬列表詳析

    這篇文章主要給大家介紹了關(guān)于antd?3.x?Table組件如何快速實(shí)現(xiàn)虛擬列表的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用antd具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-11-11
  • React組件學(xué)習(xí)之Hooks使用

    React組件學(xué)習(xí)之Hooks使用

    這篇文章主要介紹了React hooks組件通信,在開發(fā)中組件通信是React中的一個(gè)重要的知識點(diǎn),本文通過實(shí)例代碼給大家講解react hooks中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-08-08
  • 在?React?Native?中給第三方庫打補(bǔ)丁的過程解析

    在?React?Native?中給第三方庫打補(bǔ)丁的過程解析

    這篇文章主要介紹了在?React?Native?中給第三方庫打補(bǔ)丁的過程解析,有時(shí)使用了某個(gè)React Native 第三方庫,可是它有些問題,我們不得不修改它的源碼,本文介紹如何修改源碼又不會意外丟失修改結(jié)果的方法,需要的朋友可以參考下
    2022-08-08
  • antd之RangePicker設(shè)置默認(rèn)值方式

    antd之RangePicker設(shè)置默認(rèn)值方式

    這篇文章主要介紹了antd之RangePicker設(shè)置默認(rèn)值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • React通過hook實(shí)現(xiàn)封裝表格常用功能

    React通過hook實(shí)現(xiàn)封裝表格常用功能

    這篇文章主要為大家詳細(xì)介紹了React通過hook封裝表格常用功能的使用,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下
    2023-12-12
  • Redux thunk中間件及執(zhí)行原理詳細(xì)分析

    Redux thunk中間件及執(zhí)行原理詳細(xì)分析

    redux的核心概念其實(shí)很簡單:將需要修改的state都存入到store里,發(fā)起一個(gè)action用來描述發(fā)生了什么,用reducers描述action如何改變state tree,這篇文章主要介紹了Redux thunk中間件及執(zhí)行原理分析
    2022-09-09
  • react-router v4如何使用history控制路由跳轉(zhuǎn)詳解

    react-router v4如何使用history控制路由跳轉(zhuǎn)詳解

    這篇文章主要給大家介紹了關(guān)于react-router v4如何使用history控制路由跳轉(zhuǎn)的相關(guān)資料,文中通過示例代碼介紹的的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 解決antd的Table組件使用rowSelection屬性實(shí)現(xiàn)多選時(shí)遇到的bug

    解決antd的Table組件使用rowSelection屬性實(shí)現(xiàn)多選時(shí)遇到的bug

    這篇文章主要介紹了解決antd的Table組件使用rowSelection屬性實(shí)現(xiàn)多選時(shí)遇到的bug問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論