第 006 期 React 運(yùn)行時性能優(yōu)化之減少渲染組件的次數(shù)

減少組件的渲染次數(shù),能提升 React App 的運(yùn)行時性能。通過寫法的優(yōu)化,可以減少不必要的組件渲染次數(shù)。

優(yōu)化寫法

1. 組件 Render 時,避免 state, props 沒變的子組件 Render

組件 Render 會導(dǎo)致的其子組件 Render,即使子組件的 state, props 沒變。

子組件用 PureComponent 和 React.memo 可以避免這種情況下的 Render。類組件用 PureComponent,函數(shù)組件用React.memo。示例:

// 類組件
class class ClassComp extends React.PureComponent{}

// 函數(shù)組件
function FnComp () {}
React.memo(FnComp)

2. 函數(shù)組件 Render 時,避免變化的函數(shù)屬性值,導(dǎo)致子組件 Render

函數(shù)組件中的函數(shù),每運(yùn)行一次,都會生成一個新的函數(shù)。如果這個函數(shù)是某個子組件的屬性,函數(shù) Render 一次,都會導(dǎo)致子組件的 Render。

用 useCallback 包裹函數(shù),可以避免這種情況下不必要的 Render。

const handleClick = useCallback(() => ..., [])
return (
  <ChildComp onClick={handleClick}>
)

3. 組件 Render 時,屬性值避免用箭頭函數(shù)值,導(dǎo)致子組件 Render

如果子組件的屬性值是個箭頭函數(shù),父組件每次 Render,箭頭函數(shù)都是新的,會導(dǎo)致子組件的 Render。

屬性值用實(shí)例方法,就能避免這種情況。例如:

handleClick = () => {...},
render() {
  return (
    <ChildComp onClick={handleClick}>
  )
}

Render Props 也出現(xiàn)這樣的問題。如:

<Mouse>
  {mouse => (
    <ChildComp pos={mouse}>
  )}
</Mouse>

解決方案也是將其改成實(shí)例方法:

<Mouse>
  {this.renderChild}
</Mouse>

4. 避免 Prop Drilling 導(dǎo)致的中間組件的 Render

Prop drilling 指將外層組件的 state 通過 props 一層層傳下去,傳遞到層級很深的子組件的過程。外層組件的 state 發(fā)生變化,中間組件都會 Render。

層級很深的子組件可以直接取到值,不需要中間屬性的傳遞,就能避免中間屬性的 Render。用 Context API 或 Redux,MobX 等狀態(tài)管理工具可以讓子組件直接取到值。用 Context API 的示例:

// 父組件提供數(shù)據(jù)
<ThemeContext.Provider value={{ theme: this.state.theme }}>
  <Comp1>
    <Comp2>
      <Comp3>
        <ThemeContext.Consumer>
          {({theme}) => {
            // 子組件拿值
          }}
        </ThemeContext.Consumer>
      </Comp3>
    </Comp2>
  </Comp1>
</ThemeContext.Provider>

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容