自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何方便的檢測(cè)React項(xiàng)目的性能?

開發(fā) 前端
React本身就內(nèi)置了性能檢測(cè)組件 —— Profiler,可以很方便的檢測(cè)React項(xiàng)目的性能。

大家好,我卡頌。

對(duì)于長(zhǎng)期迭代的React項(xiàng)目,性能是不能忽視的問(wèn)題。通常我們通過(guò):

  • React-Dev-Tools的Profiler面板
  • 一些第三方工具,比如why-did-you-render[1]

檢測(cè)運(yùn)行時(shí)性能瓶頸。

實(shí)際上,React本身就內(nèi)置了性能檢測(cè)組件 —— Profiler,可以很方便的檢測(cè)React項(xiàng)目的性能。

使用方式

Profiler是個(gè)內(nèi)置組件,用他包裹需要檢測(cè)性能的組件即可:

<Profiler id="App" onRender={onRender}>
  <App />
</Profiler>

嵌套使用也是可以的:

<App>
  <Profiler id="Sidebar" onRender={onRender}>
    <Sidebar />
  </Profiler>
  <Profiler id="Content" onRender={onRender}>
    <Content />
  </Profiler>
</App>

Profiler會(huì)檢測(cè)被他包裹的組件樹的性能,檢測(cè)結(jié)果會(huì)作為onRender回調(diào)的參數(shù):

function onRender(
  id, 
  phase, 
  actualDuration, baseDuration, 
  startTime, commitTime
) {
  // ...回調(diào)
}

那么,這些參數(shù)都是什么意思呢?其實(shí)我們完全沒必要記這些。

我們只需要知道,一些典型的性能優(yōu)化場(chǎng)景該使用哪些參數(shù)就行。

場(chǎng)景1:組件是不是嵌套更新?

對(duì)于一般的組件更新,會(huì)經(jīng)歷4個(gè)步驟:

  1. 組件觸發(fā)更新
  2. 計(jì)算更新的影響
  3. 執(zhí)行DOM操作
  4. 視圖更新

但如果在上一次更新流程的4個(gè)步驟還未走完的情況下,又觸發(fā)新的更新:

可以發(fā)現(xiàn),在這種情況下,「視圖更新」的時(shí)機(jī)遠(yuǎn)滯后于一般更新流程,這會(huì)造成頁(yè)面交互卡頓。

這就是「組件嵌套更新」,通常我們?cè)趗seLayoutEffect中觸發(fā)新的更新會(huì)遇到這種情況。

Profiler onRender回調(diào)的phase參數(shù),用來(lái)表示組件所處更新階段:

  • mount,代表組件是首屏渲染。
  • update,代表組件更新。
  • nested-update,代表組件嵌套更新。

通過(guò)該參數(shù)可以判斷組件是否處于嵌套更新。

當(dāng)遇到嵌套更新造成的性能問(wèn)題,可以考慮用useEffect替代useLayoutEffect。

場(chǎng)景2:性能優(yōu)化到底起沒起作用?

當(dāng)提到「性能優(yōu)化」,很多同學(xué)第一反應(yīng)就是:

  • useCallback
  • useMemo
  • React.memo

但當(dāng)我們使用這些性能優(yōu)化API后,我們?cè)趺粗佬阅苁欠褡兊酶茫?/p>

為了檢測(cè)優(yōu)化效果,通常會(huì)在關(guān)鍵組件打印個(gè)log,如果狀態(tài)更新后log沒打印,代表組件沒有render,命中緩存成功,比如這樣:

function App() {
  console.log('App render')
  // ...省略邏輯
}

但這樣并不能反映性能優(yōu)化的整體效果。這時(shí)候可以考慮Profiler中的actualDuration與baseDuration參數(shù):

  • baseDuration衡量組件子樹在不命中任何緩存時(shí),完整render一次所花時(shí)間。
  • actualDuration衡量組件子樹實(shí)際完整render一次所花時(shí)間。

所以,用baseDuration減去actualDuration剩余的時(shí)間,就是性能優(yōu)化節(jié)約的時(shí)間。

比如,對(duì)下面的<App/>組件性能優(yōu)化后,只需要在onRender中比較baseDuration與actualDuration之間的差就能度量<App />的性能優(yōu)化效果:

<Profiler id="App" onRender={onRender}>
  <App />
</Profiler>

這個(gè)值越高,代表性能優(yōu)化效果越好。當(dāng)接近0時(shí),代表性能優(yōu)化沒有起到作用。

需要注意的是,baseDuration是通過(guò)子樹中每個(gè)組件最近render所需時(shí)間匯總求和得到的近似值,有時(shí)并不準(zhǔn)確

如果你的同事固執(zhí)的認(rèn)為所有函數(shù)props都必須用useCallback包裹,所有變量props都必須用useMemo包裹,請(qǐng)用以上數(shù)據(jù)狠狠的和他講道理。

場(chǎng)景3:項(xiàng)目的性能瓶頸在哪?

當(dāng)我們要做性能優(yōu)化時(shí),首先應(yīng)該明確 —— 項(xiàng)目的性能瓶頸在哪?此時(shí),可以用Profiler劃分幾個(gè)「待比較區(qū)域」,再分別對(duì)比actualDuration。

比如,對(duì)于下面的應(yīng)用:

<App>
  <Sidebar />
  <Content />
</App>

<Sidebar />和<Content />誰(shuí)render更耗時(shí)?

此時(shí)可以用Profiler分別包裹這兩個(gè)組件:

<App>
  <Profiler id="Sidebar" onRender={onRender}>
    <Sidebar />
  </Profiler>
  <Profiler id="Content" onRender={onRender}>
    <Content />
  </Profiler>
</App>

再分別在onRender中衡量actualDuration,值比較高的區(qū)域render更耗時(shí)。

這種方式定制性比較高。如果想更直觀比較哪些組件render更耗時(shí),可以使用React Dev Tools中Profiler面板的火炬圖。

總結(jié)

Profiler是React內(nèi)置的性能分析組件,用于度量其包裹的子樹的渲染性能。

最后說(shuō)個(gè)有意思的細(xì)節(jié) —— 在官網(wǎng)Profiler部分[2]中只介紹了Profiler有onRender這個(gè)回調(diào)。

從Profiler源碼看,他還存在:

  • onCommit回調(diào)
  • onPostCommit回調(diào)
  • onNestedUpdateScheduled回調(diào)

不知道為什么,他們沒有在文檔中提及。

參考資料

[1]why-did-you-render:https://www.npmjs.com/package/@welldone-software/why-did-you-render。

[2]官網(wǎng)Profiler部分:https://react.dev/reference/react/Profiler。

責(zé)任編輯:姜華 來(lái)源: 魔術(shù)師卡頌
相關(guān)推薦

2022-11-09 11:50:21

2023-04-07 15:12:46

ReactReact-Intl

2010-04-13 14:43:37

Oracle性能檢測(cè)

2023-07-04 07:30:35

React開發(fā)樣式

2022-08-03 09:11:31

React性能優(yōu)化

2024-05-13 08:16:59

React任務(wù)調(diào)度鏈表結(jié)構(gòu)

2020-09-16 14:39:13

ReactJavaScript框架

2020-03-11 20:38:13

JavaScript前端工具

2023-07-19 15:45:47

ReactDOM輕量級(jí)

2023-04-14 09:01:23

2024-01-29 09:29:02

計(jì)算機(jī)視覺模型

2009-02-04 15:55:31

敏捷開發(fā)敏捷項(xiàng)目項(xiàng)目經(jīng)理

2020-03-13 07:32:18

物聯(lián)網(wǎng)項(xiàng)目物聯(lián)網(wǎng)IOT

2015-07-07 10:11:39

GitHub項(xiàng)目流行度

2021-04-14 08:20:46

Lighthouse工具性能檢測(cè)

2024-07-18 08:08:06

2022-10-31 11:09:48

物聯(lián)網(wǎng)智能建筑

2021-08-27 14:26:06

開發(fā)技能React

2023-06-20 18:33:00

DOM框架React

2020-07-13 10:26:41

CIOIT項(xiàng)目技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)