React
Optimize
Hooks
memo
OptimizeRender
React 優化項目系列,減少大量且不必要的元件重新渲染週期
如何觸發更新的
紀錄 props value
紀錄 func 記憶體位置
紀錄 object value 避免重複執行相關處理
再開始之前先來了解什麼樣的情況會使得元件更新
props
: 父層傳進來的 props 變動state
: 元件本身 state 變動context
: 上層 context 變動re-evaluating
重新執行(評估)re-render
重新渲染觸發到元件更新時,React 會先做出 re-evaluating
用這次更新的虛擬 DOM 比對上次真實 DOM 的 snapshot
,這僅僅是 React 重新執行,不代表真實 DOM 的各個部分被重新渲染,而當比對 snapshot
發現需要更新時才去做 re-render
對 Real DOM
做更新。
先來看看 components render 情況,下例是三層元件
RenderTry
引用 DemoOutput
引用 Paragraph
RenderTry
showParagraph
並傳入 DemoOutput
DemoOutput
props.show
並傳入 children
至 Paragraph
Paragraph
props.childrend
並顯示可以看到跑了一組 APP RUNNING
(包含裡面元件的 log)
點擊按鈕時又會再跑一組 APP RUNNING
,之後的每次點擊都會再跑一組
因為有更新顯示所以 Real DOM 也會更新
這樣是沒問題的 因為 RenderTry
更新了 state
處發了更新並連同底下的元件也被觸發了更新。
DemoOutput
這個元件把傳進 DemoOutput
的 props
寫死,測試不讓 DemoOutput
元件重新渲染
發現APP RUNNING
還是一樣跑了一組,但 Real DOM 沒有變化。
因為父元件 RenderTry
更新了 state
代表他整個元件都更新了,所以會連同在內的元件都做了 re-evaluation
的更新,但因為經 re-evaluation
評估後 Real DOM 是不需要更新的,所以沒有執行 re-render
。
為了要減少 React 不必要的 re-evaluation
可以使用 React.memo
React.memo()
使用
React.memo
儲存之前的 props value
重新整理跑出一組 APP RUNING
,但之後點擊按鈕更新 state 都只有父層做更新而已。
那我是不是趕緊把所有元件都加上 memo 啦!
他會去做兩件事:
所以建議是在底下有多層時,加在較上層的元件入口,例如範例一樣,不是加再最底層的
Paragraph
元件上,而是加在元件樹的根源處DemoOutput
上。
繼續往下看 React.useCallback