React Developer Tools(Components/Profiler)の使い方
React Developer Tools
React のデバッグツールのこと。
コンポーネントに対して、どの props が渡されているか、現在のstateの値、コンポーネント内部で使用されている可能性のある Hooks などを確認することができる。
また、コンポーネントがレンダリングにかかる時間や再レンダリングされる原因などを特定することもできる。
React Developer Tools には、「Profiler」と「Component」の2種類のタブがあります。
Profiler
特定の component のレンダリング時間やその回数などを確認したり、レンダリング原因を特定することができます。
使い方は下記の通り。(下記の説明は、ドキュメントから抜粋したもの。)
まずは、パフォーマンス測定の方法について説明します。
はじめに Profiler タブをクリックし、そのすぐ下に青い丸いボタンと矢印が一回りしているボタンがあるをことを確認してください。
次に、矢印が一回りしているボタンをクリックすると、ページ更新され、測定開始になります。
その後、ページ更新が終了したら、青いボタンをクリックすることで、測定終了になります。
測定開始から終了までの間に、state や props を動かす動作を画面上で行うこと(例えば、入力フォームの値がstateで管理されており、その入力フォームに値を入力するなど)で、使用しているコンポーネントのレンダリングデータ(レンダリングにかかった時間など)を取得することができます。
React には、「レンダリングフェーズ」と「コミットフェーズ」の2つのフェーズがあります。
レンダリングフェーズ
DOMにどのような変更を加えるのか決定します。このフェーズでは、Reactはrenderを呼び出し、その結果を前回のrenderと比較します。
コミットフェーズ
React が変更を適用します(React DOMの場合、これはReactがDOMノードを挿入、更新、削除するときである)。 Reactはこのフェーズで、componentDidMount(コンポーネントがマウントされた後ですぐに実行される関数)やcomponentDidUpdate(コンポーネントのpropsやstateが変更されたときに実行される関数)などのライフサイクルも呼び出します。
React Profiler では、コミットごとにパフォーマンス情報をグループ化し、そのコミットは下記のような棒グラフで表されます。
グラフの各バーはひとつのコミットを表し、現在選択されているコミットは青く塗られています。 それぞれのバーの色と高さは、そのコミットのレンダリングにかかった時間に対応しています。
高さが高いバーは、コミットが遅く、高さの低いバーよりもレンダリングに時間がかかっているということを表しています。
プロファイリングを長くすればするほど、アプリケーションのレンダリング回数は増えます。
場合によっては、コミットの数が多すぎて簡単に処理できないかもしれません。
Profiler にはフィルタリング機能があります。
これを使用し、しきい値を指定すると、その値よりも高速なコミットをすべて非表示にすることができ、レンダリングコストが高いコンポーネントを特定することができます。
フィルタリングは、上記画像の「⚙️」マーク をクリックし、「Hide commits below」という箇所の入力フォームに値を入力することで、指定したミリ秒以上のコミットだけが表示されるようになります。
下記画像は、「Hide commits below」であるしきい値を設定する前と後になります。
例えば、しきい値を 800ms にすると、レンダリング時間が 800ms 以上のコミットのみ表示するようにすることができ、レンダリングコストが高い(=レンダリングに時間がかかる)コンポーネントを特定することができます。
また、コミットがいつ行われたか(Commited at)、コミットにかかった時間(Render duration)、有効な場合はコミットのトリガーとなったインタラクション(Interactions)などの特定のコミットに関する情報も取得することもできます。
これは、各バーの横に表示される情報のことを指します。
下記画像は、コミット情報を表した画面のスクショになります。
この画面は、プロファイリングした直後か、コンポーネントを選択していない時か、コンポーネントを選択していても他の場所をクリックしていて非選択状態にするか、下記の画像のように「×」ボタンをクリックすることで、表示することができます。
また、コンポーネントにカーソルをホバーするだけでもコミット情報を取得することはできます。
下記画像が、コンポーネントにカーソルをホバー時のコミット情報を取得した状態になります。
上記の状態だと、 ChildComponent コンポーネント自身は、レンダリングに 183.3 ms かかり、ChildComponent コンポーネントおよびそれに関連するすべての子コンポーネントが描画されるのにかかった合計時間が183.7 ms という意味を表しています。
ここから、コミット間を移動することができる矢印(画像の青い線で囲ったところ)をクリックし、コミット間を移動させることで、さらにコミットごとのコミット情報を取得することができます。
これは、不要なレンダリングを引き起こす可能性のある props 、state、hooks を特定するのに役立ちます。
下記画像は、1回矢印(画像の青い線で囲ったところ)をクリックし、コミット間を移動させた画面のスクショ画像になります。
"What caused this to update?” はレンダリングされた原因を指します。この画像だと、ExpensiveComponent が レンダリングの原因のようです。
さらに、ここから、各コンポーネントをクリックし、選択することで、コンポーネントがレンダリングされた理由や、プロファイリング中に記録されたすべてのコミットのリストなど、さらに詳細な情報が表示されます。
その状態の画面のスクショが下記になります。
上記の画像は、ChildComponent コンポーネントをクリックしました。
画像に表示されている「Rendered at:」は、選択したコンポーネントがレンダリングされた「タイミング」を表します。
なので、Child Component コンポーネントは複数回に渡り、レンダリングされているということになります。
例えば、「Rendered at:」の一番上の「0.9s for 496.8ms」は、プロファイリングが開始されてから0.9秒後に、Child Component コンポーネントがレンダリングされたという意味になります。
また、Child Component コンポーネントのレンダリングにかかった時間が496.8ミリ秒という意味になります。
次に、上記のコンポーネントを選択した状態で「Components」タブをクリックすることで、そのコンポーネントに渡しているpropsやstate などを右側のパネルから確認することができます。
これは、不要なレンダリングを引き起こす可能性のある props 、state、hooks を特定するのに役立ちます。
また、場合によっては、コンポーネントを選択し、コミット間をステップすることで、そのコンポーネントがレンダリングされた理由のヒントが得られることもあります。
下記画像は、ChildComponent というコンポーネントを選択し、コミット間でステップし、レンダリングされた理由を確認する手順になります。
上記画像の番号順に実行することで、特定のコンポーネントがレンダリングされた理由や特定のコミットに対するレンダリング時間などを確認することができます。
次に測定結果の表示方法について説明します。
パフォーマンス測定の測定結果の表示方法には、「フレームチャート」と「ランクチャート」の2種類あります。
フレームチャート
特定のコミットにおけるアプリケーションの状態を表します。
チャートの各バーは、React コンポーネント(App など)を表します。 (ここでいうバーは、先ほどの縦長のものではなく、横長のバーを指します)
バーのサイズと色は、コンポーネントとその子のレンダリングにかかった時間を表しています。
バーの幅は、コンポーネントが最後にレンダリングされたときに費やされた時間を表し、色は、現在のコミットの一部として費やされた時間を表します。
注意
バーの幅は、コンポーネント(およびその子コンポーネント)が最後にレンダリングされたときに、レンダリングにかかった時間を示します。
このコミットの一部としてコンポーネントが再レンダリングされなかった場合、時間は以前のレンダリングを表します。
バーの色は、選択したコミットでコンポーネント(およびその子コンポーネント)のレンダリングにかかった時間が多いもので色分けしています。
黄色のコンポーネントはより時間がかかり、青色のコンポーネントはより時間がかからず、灰色のコンポーネントはこのコミット中にまったくレンダリングされていないということを表します。
ランクチャート
単一のコミットの中で、レンダリングに最も時間がかかったコンポーネントから順に並べられた状態を表した結果になります。
なので、最も遅い(レンダリングコストが高い)コンポーネントが一番上に、最も速いコンポーネントが一番下に表示されます。
これにより、どのコンポーネントがパフォーマンスに最も影響を与えているかを簡単に特定することができます。
なので、もし、1つのコンポーネントに起因するパフォーマンス上の問題がある場合、このチャートを使えば、非常に簡単に対象のコンポーネントを特定できるはずです。
ランク付けされたチャートも、コンポーネントをクリックすることで、そのコンポーネントを選択することができ、そのコンポーネントの情報を取得することができます(取得内容は先ほどのフレームチャートと同じになります)。
注意
コンポーネントのレンダリング時間には、その子コンポーネントのレンダリングにかかった時間も含まれるため、レンダリングに最も時間がかかったコンポーネントは、一般的にツリーの先頭(コンポーネント全体での上の方)付近にあります。
Components
Componentsタブは、各コンポーネントの props や state を確認することができます。
ここに記載されている propsやstate は画面上から編集することができます。
また、「Components」タブには、下記のような機能もあります。
- 「<>」マークは、選択したコンポーネントが存在するSourceファイルへ移行することができます。
- 「👀」マークは、コンポーネントのDOMを確認することができます。
- 「🐞」マークは、componentのデータ(propsやstateなど)をコンソールに記録することができます。
下記の画像は、ExpensiveComponent コンポーネントを選択し、「🐞マーク」をクリックすることで、「Console」タブにコンポーネントのデータ(propsやstateなど)を算出させたものになります。
参考
Discussion