最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一、引子

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

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

二、代碼范式

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

2.1 Memo 緩存組件

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

子組件的渲染有些情況,子組件控制不住,它受到父組件的參數(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 父組件層面,對(duì)象使用 useMemo

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

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

  const id = React.useId();

  // Age 屬性的變更不會(huì)影響 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 可能會(huì)傳入一個(gè)對(duì)象,利用useMemo 或者 useCallback 來(lái)保護(hù) App 組件不會(huì)做出過(guò)多重渲染。

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

2.4 其他

還有一種特殊情況是:不規(guī)范、分批的 Context 調(diào)用導(dǎo)致了頁(yè)面的重新渲染。針對(duì)一些老舊項(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 的記錄圓圈
  • 刷新頁(yè)面或者做其他操作
  • 停止記錄
  • 參考快照記錄

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

3.3 渲染打印工具

ahooks的useWhyDidYouUpdate

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

Welldone Software 的 why-did-you-render

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

四、總結(jié)

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

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

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

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

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

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

相關(guān)文章

  • 解決React報(bào)錯(cuò)Property 'X' does not exist on type 'HTMLElement'

    解決React報(bào)錯(cuò)Property 'X' does not 

    這篇文章主要為大家介紹了解決React報(bào)錯(cuò)Property 'X' does not exist on type 'HTMLElement',有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React 的調(diào)和算法Diffing 算法策略詳解

    React 的調(diào)和算法Diffing 算法策略詳解

    React的調(diào)和算法,主要發(fā)生在render階段,調(diào)和算法并不是一個(gè)特定的算法函數(shù),而是指在調(diào)和過(guò)程中,為提高構(gòu)建workInProcess樹(shù)的性能,以及Dom樹(shù)更新的性能,而采用的一種策略,又稱(chēng)diffing算法
    2021-12-12
  • React?Hooks項(xiàng)目實(shí)戰(zhàn)

    React?Hooks項(xiàng)目實(shí)戰(zhàn)

    React?Hooks是React?16.8版本引入的新特性,它使得在函數(shù)組件中也能夠使用狀態(tài)(state)和其他React特性,本文就來(lái)詳細(xì)介紹一下React?Hooks項(xiàng)目實(shí)戰(zhàn),感興趣的可以了解一下
    2023-11-11
  • React實(shí)現(xiàn)骨架屏的示例代碼

    React實(shí)現(xiàn)骨架屏的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)React自動(dòng)化實(shí)現(xiàn)骨架屏,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • React Native按鈕Touchable系列組件使用教程示例

    React Native按鈕Touchable系列組件使用教程示例

    這篇文章主要為大家介紹了React Native按鈕Touchable系列組件使用教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • react實(shí)現(xiàn)移動(dòng)端下拉菜單的示例代碼

    react實(shí)現(xiàn)移動(dòng)端下拉菜單的示例代碼

    這篇文章主要介紹了react實(shí)現(xiàn)移動(dòng)端下拉菜單的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • flouting?ui定位組件完美替代ant?deisgn使用詳解

    flouting?ui定位組件完美替代ant?deisgn使用詳解

    這篇文章主要為大家介紹了flouting?ui定位組件完美替代ant?deisgn使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • React實(shí)現(xiàn)Step組件的示例代碼

    React實(shí)現(xiàn)Step組件的示例代碼

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)Step組件(步驟條組件)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的示例代碼

    React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)文件上傳和斷點(diǎn)續(xù)傳功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • React中useMemo與useCallback區(qū)別以及各自解決什么性能問(wèn)題、依賴(lài)陷阱詳解

    React中useMemo與useCallback區(qū)別以及各自解決什么性能問(wèn)題、依賴(lài)陷阱詳解

    useCallback和useMemo是一樣的東西,只是入?yún)⒂兴煌?這篇文章主要介紹了React中useMemo與useCallback區(qū)別以及各自解決什么性能問(wèn)題、依賴(lài)陷阱的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2026-05-05

最新評(píng)論

固安县| 江源县| 宝坻区| 滕州市| 青海省| 正阳县| 江陵县| 乐昌市| 门头沟区| 洞头县| 石城县| 怀安县| 尖扎县| 沙田区| 安顺市| 阿拉善左旗| 郴州市| 海伦市| 宣威市| 应城市| 清水河县| 会东县| 呼图壁县| 上饶市| 嘉峪关市| 泽州县| 西平县| 永登县| 大同市| 凌源市| 太白县| 什邡市| 梓潼县| 杭州市| 武山县| 新竹县| 尉犁县| 绵竹市| 左云县| 灵武市| 渑池县|