Inspector のパフォーマンス
Inspectorの Performance タブは、実行中のアプリケーションのフレームを記録して時間に沿ってチャート表示し、遅いフレームを見つけて、何がそれを遅らせたのかを確認できます。MiniStatsがアプリケーションを使っている間の最近の平均を表示するのに対し、Performance タブはキャプチャのすべてのフレームを最新の1000フレームまで保持し、フレームを比較したり1つずつ確認したりできます。
記録
記録ボタン(点を囲むリング)を押すと、すべてのフレームを記録します。記録中は赤く表示され、もう一度押すと停止します。その隣のボタンはキャプチャをクリアします。
チャートはキャプチャ全体を時間に沿って表示します。各フレームはかかった時間の分の幅を持つため、遅いフレームはそれだけの場所を占めます。2回の記録の間のように1秒より長い間隔は、その長さを示す区切りマークに折りたたまれます。上から順に次のとおりです。
| チャート | 表示内容 |
|---|---|
| Frame | フレーム間隔。 |
| CPU | メインスレッドの時間をフェーズ別に表示します。システムの更新、物理、スクリプト、アニメーション、ポストアップデート、レンダー、Inspector 自身の時間です。 |
| GPU | GPU timings をオンにしたときのフレームの GPU 時間。 |
| Draw calls | ドローコール。エンジンが種類別に数える場合は種類別に表示します。 |
| Scripts | Script timing をオンにしたときの、各スクリプトタイプの時間。スクリプトの計測を参照してください。 |
| Counters | アプリケーションが app.stats.user に保持するカウンター。カウンターを参照してください。 |
| Loading | ページとアプリケーションのマイルストーン、ロード中のアセット、処理中のリクエスト。ロードを参照してください。 |
| Memory | JavaScript ヒープ、ビデオメモリとその種類別の内訳を、スケールを共有する線で表示します。 |
| Resources | テクスチャ、レンダーターゲット、シェーダー、バッファ、WebGPU ではパイプラインの数。 |
| Events | イベントの種類ごとの行で、そのイベントがあったフレームを示します。イベントを参照してください。 |
Frame、CPU、GPU のチャートでは、破線がディスプレイの間隔を示します。チャートにカーソルを合わせるとポインターの下のフレームの数値が、マークに合わせると何が起きたかが表示されます。チャートやセクションの名前をクリックすると折りたたまれ、チャートの横のリストで線のチェックを外すと非表示になり、チャートは残りの線に合わせてスケールし直します。名前とチャートの間の区切り線をドラッグすると、名前の列を広げられます。
キャプチャの一部を見るには、次のようにします。
- フレームをクリックすると、そのフレームがフレームのタイムラインに表示され、記録されたすべての内容が下のプロパティビューに表示されます。
- チャートの上をドラッグすると、複数のフレームをまとめて選択し、その平均、95パーセンタイル、最大値を確認できます。タイムラインにはそれらの平均フレームが表示されます。
- チャートの上でスクロールするとズームし、下のスクロールバーをドラッグするか、Shift を押しながらチャートの上をドラッグするとパンします。ダブルクリックするとキャプチャ全体の表示に戻ります。
- ‹ と › で1フレームずつ移動し、« で最初のフレームを、» で最新のフレームを表示し、記録に合わせて追従します。パネルにフォーカスがある間は、矢印キーで1フレームずつ(Shift で10フレームずつ)移動し、Home で最初のフレームを表示し、End で最新のフレームに追従します。
イベント
| イベント | 示すもの |
|---|---|
| Hitches | 何が原因であれ、中央値のフレームの2倍以上の時間がかかったフレーム。ユーザーにカクつきとして見えるフレームです。 |
| Thread blocked | Chromium 系のブラウザが報告する、ブラウザのメインスレッドが50ミリ秒以上ビジーだったフレームと、最も長く実行されたスクリプト。フレームが遅くなった理由を示します。これのないヒッチは GPU、ブラウザ、ディスプレイによって遅れたもので、ヒッチのホバー表示にそのことが示されます。 |
| Lightmaps | ライトマッパーを持つアプリケーションで、ライトマッパーがベイクしたライトマップ。 |
| Shaders | コンパイルまたは作成されたシェーダーと、作成されたレンダーパイプライン。 |
| Heap shrank | JavaScript ヒープの縮小、つまりガベージコレクション。 |
| Resources | 作成または破棄されたテクスチャ、レンダーターゲット、バッファ。 |
| Measures | アプリケーションが performance.measure で計測した区間。 |
フレームのタイムライン
チャートの下のタイムラインは、選択したフレームをその時間に沿ってフレイムチャート(flame chart)として表示します。
- CPU の行には、アップデート、ポストアップデート、Inspector、レンダーと、実行された位置にライトマップのベイクが表示されます。その下の行はそれらを細かく分けて表示します。物理のステップとアニメーション、レンダーのフェーズ、そしてスクリプトの計測をオンにした場合はアップデートとポストアップデートのスクリプトと、それをスクリプトタイプ別に分けた行です。
- GPU の行には、ブルームや被写界深度などのエフェクトと、その下に各エフェクトが実行するパス、そしてエフェクトに属さないパスが表示されます。GPU の計測を参照してください。
- Events の行には、メインスレッドの長いタスクと
performance.measureで計測された区間が表示され、その下の行にはフレームのマイルストーン、アセット、リクエストが表示されます。
バーにカーソルを合わせるとその時間が、行に合わせるとその行のすべての内容が表示されます。スクリプトタイプをクリックすると Scripts タブに、パスやエフェクトをクリックすると Frame graph タブに、アセットをクリックすると Assets タブに表示されます。タイムラインの上でスクロールするとフレームの一部にズームし、下のスクロールバーをドラッグするか、Shift を押しながらドラッグするとパンし、ダブルクリックするとフレーム全体の表示に戻ります。タイトルをクリックすると折りたたまれます。
下のプロパティビューには、そのフレームについて記録されたすべての内容が一覧表示されます。何がフレームを遅らせたか、フェーズ別の CPU 時間、各パスの GPU 時間、スクリプト、カウンター、ロードされたもの、送信した処理、メモリとリソース、イベントです。
GPU の計測
GPU timings をオンにすると、GPU の時間を記録します。WebGPU では各パスが計測され、パスのエフェクトはフレームグラフから、そのパスを実行するパスとして求められます。フレームグラフが計測したパスと一致しなくなった場合は、すべてのパスが GPU の行に表示されます。同じ名前のパスが連続する場合は Downsample ×5 のように1つのラベルにまとめられ、フレームの詳細にはそれぞれの時間が一覧表示されます。WebGL ではフレーム全体を1つとして計測します。
スクリプトの計測
Script timing をオンにすると、記録中に各スクリプトタイプを計測します。その update、postUpdate、initialize の呼び出しの時間を、その中で呼ばれた呼び出しを除いて計測し、それぞれが何回呼ばれたかも記録します。CPU チャートではスクリプトが他のシステムと分けて表示され、タイムラインではスクリプトが実行された位置に描画されます。
Scripts チャートは、まとめて選択したフレーム、または選択がなければキャプチャ全体で最も時間のかかった10個のスクリプトタイプを積み上げて表示するため、スパイクを選択するとその原因のスクリプトが前面に出てきます。残りは1つの帯にまとめられ、そのホバー表示に一覧が表示されます。リストの下の ▸ 10 more で、さらに10個のタイプに独自の帯を割り当てます。時間に関係なくスクリプトを追い続けるには、フレームの詳細の横にある Pin を押すか、リストで Shift+クリックしてピン留めします。リストの行を Alt+クリックするとその行だけを表示し、もう一度 Alt+クリックするとすべてを表示します。
呼び出しの計測には、Inspector の時間として数えられる約0.5マイクロ秒のコストがかかります。イベントハンドラー、タイマー、Promise で費やされた時間は数えられません。クロスオリジン分離されていないページでは、ブラウザのクロックが0.1ミリ秒刻みになるため、小さなスクリプトの時間は多くのフレームをまとめて選択したほうが正確に読み取れます。
ロード
Loading セクションは、チャートと同じ時間軸を共有します。
- Milestones は、ページとアプリケーションの節目を示します。ページの到着、DOM の準備完了、最初のペイント、プリロード、アプリケーションの開始と最初のフレームです。
- Assets は、各アセットのロードを、要求してからそのリソースの準備ができるまで表示します。ファイルのリクエストは濃く、パースなどその後の処理は薄く表示されます。色はアセットの種類を示し、行の名前のツールチップに凡例があります。失敗したものは赤で表示されます。
- Requests は、ページのリクエストがいくつ処理中だったかをチャート表示します。
セクションにカーソルを合わせるとロード中だったものが表示され、アセットをクリックすると Assets タブに表示されます。
アプリケーションの起動の記録
アプリケーションが最初に実行するフレームから記録するには、Inspector に record: true を渡すか、EntityInspector スクリプトの record 属性を設定します。app.init() の直後のように、アプリケーションが最初のフレームを実行する前に作成すると、Inspector はアプリケーションの起動も記録します。
const app = new AppBase(canvas);
app.init(createOptions);
// recording before the first frame records the start of the application too
const inspector = new Inspector(app, { record: true });
app.start();
キャプチャはその後、ページが開いてから最初のフレームまでの Startup エントリから始まり、ページのリクエスト、マイルストーン、ロードされたアセット、メインスレッドがブロックされた時間を含みます。その詳細には、かかった時間、ロードされたもの、シェーダーのコンパイル、そしてリクエストと処理を分けた最も遅いアセットが一覧表示されます。これはキャプチャの1000エントリの1つなので、他のエントリと同じように新しいフレームに場所を譲ります。
コードから inspector.recording を設定すると、アプリケーションの一部の前後でキャプチャを開始または停止できます。
// once the part to look at has run
inspector.recording = false;
カウンター
Counters セクションは、アプリケーションが app.stats.user に保持するカウンターを、各フレームの終了時の値でチャート表示します。単位はアプリケーションが決めるため、カウンターごとに独自のスケールを持つ線で表示されます。フレームの詳細にはその値が、まとめて選択したフレームではその平均、95パーセンタイル、最大値が一覧表示されます。カウンター自体については AppStatsによるプロファイリングを参照してください。
// counted afresh each frame
app.on('frameupdate', () => app.stats.user.set('enemies', 0));
// wherever the application counts them
app.stats.user.set('enemies', app.stats.user.get('enemies') + 1);
エンジンのビルド
エンジンのリリースビルドは、アップデートとレンダーをそれぞれ全体として計測します。プロファイラービルドとデバッグビルドでは、バッチャーによるバッチの更新と作成を含むレンダーのフェーズ、ドローコールの内訳、シェーダーのコンパイル、ライトマップのベイクが追加されます。
Inspector はアプリケーションのアップデートの中で実行されるため、その時間は Inspector として分けて表示されます。Inspector time をオフにすると CPU チャートから除外され、チャートはアプリケーション自身の時間に合わせてスケールします。
数値のコピー
タブの名前を右クリックするとキャプチャ全体(各フレームとその記録内容すべて)を、チャートやセクションの名前、またはそのリストの行を右クリックするとその系列をフレームごとに1行として、JSON またはスプレッドシート用の CSV でコピーします。どちらも、まとめて選択したフレームがある場合はそれらのフレームが対象になります。チャートでフレームを右クリックするとそのフレームを、まとめて選択したフレームの中で右クリックするとその数値を、タイムラインを右クリックするとそのバーをコピーします。