新聞中心
大家好,我卡頌。

創(chuàng)新互聯(lián)專注于馬鞍山網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供馬鞍山營(yíng)銷型網(wǎng)站建設(shè),馬鞍山網(wǎng)站制作、馬鞍山網(wǎng)頁(yè)設(shè)計(jì)、馬鞍山網(wǎng)站官網(wǎng)定制、微信平臺(tái)小程序開(kāi)發(fā)服務(wù),打造馬鞍山網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供馬鞍山網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
對(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會(huì)檢測(cè)被他包裹的組件樹(shù)的性能,檢測(cè)結(jié)果會(huì)作為onRender回調(diào)的參數(shù):
function onRender(
id,
phase,
actualDuration, baseDuration,
startTime, commitTime
) {
// ...回調(diào)
}那么,這些參數(shù)都是什么意思呢?其實(shí)我們完全沒(méi)必要記這些。
我們只需要知道,一些典型的性能優(yōu)化場(chǎng)景該使用哪些參數(shù)就行。
場(chǎng)景1:組件是不是嵌套更新?
對(duì)于一般的組件更新,會(huì)經(jīng)歷4個(gè)步驟:
- 組件觸發(fā)更新
- 計(jì)算更新的影響
- 執(zhí)行DOM操作
- 視圖更新
但如果在上一次更新流程的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)化到底起沒(méi)起作用?
當(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沒(méi)打印,代表組件沒(méi)有render,命中緩存成功,比如這樣:
function App() {
console.log('App render')
// ...省略邏輯
}但這樣并不能反映性能優(yōu)化的整體效果。這時(shí)候可以考慮Profiler中的actualDuration與baseDuration參數(shù):
- baseDuration衡量組件子樹(shù)在不命中任何緩存時(shí),完整render一次所花時(shí)間。
- actualDuration衡量組件子樹(shù)實(shí)際完整render一次所花時(shí)間。
所以,用baseDuration減去actualDuration剩余的時(shí)間,就是性能優(yōu)化節(jié)約的時(shí)間。
比如,對(duì)下面的
這個(gè)值越高,代表性能優(yōu)化效果越好。當(dāng)接近0時(shí),代表性能優(yōu)化沒(méi)有起到作用。
需要注意的是,baseDuration是通過(guò)子樹(shù)中每個(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)用:
此時(shí)可以用Profiler分別包裹這兩個(gè)組件:
再分別在onRender中衡量actualDuration,值比較高的區(qū)域render更耗時(shí)。
這種方式定制性比較高。如果想更直觀比較哪些組件render更耗時(shí),可以使用React Dev Tools中Profiler面板的火炬圖。
總結(jié)
Profiler是React內(nèi)置的性能分析組件,用于度量其包裹的子樹(shù)的渲染性能。
最后說(shuō)個(gè)有意思的細(xì)節(jié) —— 在官網(wǎng)Profiler部分[2]中只介紹了Profiler有onRender這個(gè)回調(diào)。
從Profiler源碼看,他還存在:
- onCommit回調(diào)
- onPostCommit回調(diào)
- onNestedUpdateScheduled回調(diào)
不知道為什么,他們沒(méi)有在文檔中提及。
參考資料
[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。
本文題目:如何方便的檢測(cè)React項(xiàng)目的性能?
分享URL:http://www.5511xx.com/article/cdpgghj.html
其他資訊
- 了解Linux服務(wù)的內(nèi)容,掌握關(guān)鍵知識(shí)(linux服務(wù)有哪些內(nèi)容嗎)
- 紅色閃耀,Redis引領(lǐng)ID號(hào)成長(zhǎng)(redis來(lái)生成id)
- 數(shù)據(jù)庫(kù)硬盤:存儲(chǔ)保障你的數(shù)據(jù)安全與穩(wěn)定! (數(shù)據(jù)庫(kù)硬盤)
- 云計(jì)算的可伸縮性包括什么功能?(負(fù)載均衡器可以實(shí)現(xiàn)服務(wù)器的自動(dòng)擴(kuò)展嗎?)
- Python使用CloudflareAPI自動(dòng)修改DNS記錄教程


咨詢
建站咨詢
