[譯] React Profiler 介紹

React 16.5 添加了對新的 profiler DevTools 插件的支持。這個插件使用 React 的 Profiler 實驗性 API 去收集全部 component 的渲染時間,目的是爲了找出你的 React App 的性能瓶頸。它將會和咱們即將發佈的 時間片 特性徹底兼容。(譯者注:能夠參考 Dan 在第一屆中國 React 開發者大會上的視頻html

這篇博文包括如下的話題:前端

Profile 一個 APP

DevTools 將會對支持新的 profiling API 的 APP 新加一個 「Profiler」 tab 列:react

New DevTools

Note:react-dom 16.5+ 在 DEV 模式下才支持 Profiling,同時生產環境下也能夠經過一個 profiling bundle react-dom/profiling 來支持。請在 fb.me/react-profi… 上查看如何使用這個 bundle。android

這個 「Profiler」 的面板在剛開始的時候是空的。你能夠點擊 record 按鈕來啓動 profile:ios

Click

當你開始記錄以後,DevTools 將會自動收集你 APP 在(啓動以後)每一刻的性能數據。(在記錄期間)你能夠和日常同樣使用你的 APP,當你完成 profile 以後,請點 「Stop」 按鈕。git

Click

若是你的 APP 在 profile 期間從新渲染了幾回,DevTools 將會提供好幾種方法去查看性能數據。咱們將會 在接下來討論它們github

查看性能數據

瀏覽 commits

從概念上講,React 的運行分爲兩個階段:後端

  • render 階段會肯定例如 DOM 之類的數據須要作那些變化。在這個階段,React 將會執行(各個組件的)render 方法,以後會計算出和調用 render 方法以前有哪些變化。
  • commit 階段是 React 提交任何更改所在的階段(在 React DOM 下,就是指 React 添加、修改和移除 DOM 節點的時候)。同時在這個階段,React 會執行像 componentDidMountcomponentDidUpdate 這類周期函數。

(譯者注:此處可參考 React.js 小書第 18-20 篇app

profiler DevTools 是在 commit 階段收集性能數據的。各次 commit 會被展現在界面頂部的條形圖中:less

Bar chart of profiled commits

在條形圖中,每一列都表示單次的 commit 數據,你當前選中的 commit 列會變成黑色。你能夠點擊各個列(或者是左/右切換按鈕)來查看不一樣的 commit 數據。

這些列的顏色和高度對應着該次 commit 在渲染上所花的時間(較高、偏黃的列會比較矮、偏藍的列花費的時間多)。

篩選 commits

你 profile 的記錄時間越長,渲染次數就會越多。有時候你或許會被過多的(價值低的)commit 記錄干擾。爲了幫助你解決這個問題,profiler 提供了一個篩選功能。用它來制定一個時間閥值,以後 profiler 會隱藏全部比這個閥值更快的 commit。

Filtering commits by time

火焰圖

(譯者注:阮一峯:如何讀懂火焰圖?

火焰圖會展現你所指定的那一次 commit 的信息。圖中每一列都表明了一個 React component(例以下圖中的 AppNav)。各列的尺寸和顏色表示這列所表明的 component 及其 children 的渲染時間(列的寬度表示該 component 最近一次渲染所花費的時間,列的顏色表明在該次 commit 中渲染所花費的時間)。

Example flame chart

Note:

列的寬度表示 component(和它的 children)最近一次渲染所花費的時間。若是這個 component 在本次 commit 中沒有被從新渲染,那其所展現的時間表示上一次 render 的耗時。一個列越寬,其所表明的 component 渲染耗時就越長。

列的顏色表示在本次 commit 中該 component(和它的 children)所花費的時間。黃色表明耗時較長、藍色表明耗時較短,灰色表明該 component 在此次 commit 中沒有被(從新)渲染。

舉個例子,上圖中所展現的 commit 總共渲染耗時爲 18.4 ms。Router component 是渲染成本「最昂貴」的 component(花費了 18.4 ms)。他所花費的時間大部分在兩個 children 上:Nav(8.4 ms)和 Route (7.9 ms)。剩下的時間用於它的其餘 children 和它自身的渲染。

你能夠經過點擊 component 列來放大或縮小火焰圖:

Click on a component to zoom in or out

點擊一個 component 的同時也會選中它,它的具體信息將會展現在右邊的數據列,列裏會展現該 component 在此次 commit 時的 propsstate。你能夠去深刻研究這些數據來找出此次 commit 具體作了哪些。

Viewing a component's props and state for a commit

某些狀況下,選中一個 component 後在不一樣的 commit 之間切換也能夠發現觸發此次渲染的緣由:

Seeing which values changed between commits

上圖表示在兩次 commit 中 state.scrollOffset 被改變了。這或許就是觸發 List component 重繪的緣由。

排序圖

同火焰圖同樣,排序圖也會展現你所指定的那一次 commit 的信息,圖中每一列都表明了一個 React component(例以下圖中的 AppNav)。不一樣的是排序圖是有順序的,耗時最長的 component 會展現在第一行。

Example ranked chart

Note:

一個 component 的渲染時間也包括了它的 children 們消耗的時間,因此渲染耗時最長的 component 一般距離樹頂部最近。

和火焰圖同樣,你能夠經過點擊 component 列來放大或縮小排序圖(譯者注:排序圖只會展現在本次 commit 中被觸發重繪的 component)。

Component 圖

在你 profile 的過程當中,使用該圖查看單一 component(在屢次 commit 中)的渲染時間有時候是很是有用的。Component 圖會以一個列的形式展現,其中每一列都表示你所選擇的 component 的某一次 commit 下的渲染時間。每列高度和顏色都表示該 component 在某次 commit 中同其它組件的耗時對比。

Example component chart

上圖代表 List component 渲染了 11 次。同時還代表 List 在每次渲染中是最「昂貴」的組件。(譯者注:此處是經過列的顏色判斷)

查看這種圖的方法有兩種:雙擊一個 component 或者是選中一個 component 後點擊在右邊列中的藍色表格按鈕。你能夠經過點擊右邊列的 「x」 按鈕來返回原圖,固然你也能夠雙擊 Component 圖中的某一列來查看那次 commit 的更多信息。

How to view all renders for a specific component

若是你所選中的 component 在 profile 期間歷來沒被渲染過,則會顯示下面的信息:

No render times for the selected component

交互動做(Interactions)

React 最近添加了一個 實驗性 API,目的是爲了追蹤引發更新的緣由。被這些API所追蹤的「交互動做」也會展現在 profiler 裏:

The interactions panel

上圖展示了一個 profile 期間被追蹤的 4 個交互動做。每行都展現了一個追蹤的交互動做。每行裏帶有顏色的點表示與其交互動做所對應的 commit 記錄。

你也能夠在特定的 commit 記錄的右邊列看到在該記錄期間所被追蹤的交互動做。

List of interactions for a commit

你能夠經過點擊它們來實如今交互動做和 commits 之間的跳轉:

Navigate between interactions and commits

tracking API 仍然是很新的特性,咱們會在接下來的博客文章中詳細介紹它。

常見問題 & 解決方法

選擇的根元素下沒有 profile 數據被記錄

若是你的 APP 有好幾個 「root」(譯者注:指 React 有好幾個 root 組件),你可能會在 profile 以後看到下面的信息:

No profiling data has been recorded for the selected root

這個信息表示你在 「Elements」 界面下所選擇的 root 之下沒有性能數據被記錄。這種狀況下,請嘗試選擇一個不一樣的根元素來查看在這個 root 下的 profile 數據:

Select a root in the "Elements" panel to view its performance data

選中的 commit 記錄沒有時間數據能夠展現

有時候 commit 速度可能很是地快,以致於 performance.now() 無法提供給 DevTools 任何有意義的數據。這種狀況下,會展現下面的界面:

No timing data to display for the selected commit

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。

掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專列

相關文章
相關標籤/搜索