確実なパフォーマンス戦略の基盤は、適切な測定とインストルメンテーションです。測定できないものは最適化できません。このドキュメントでは、CRP パフォーマンスを測定するためのさまざまな方法について説明します。
- Lighthouse のアプローチでは、ページに対して一連の自動テストを実行し、ページの CRP パフォーマンスに関するレポートを生成します。この方法では、ブラウザに読み込まれた特定のページの CRP パフォーマンスの概要をすばやく簡単に確認でき、パフォーマンスのテスト、反復、改善を迅速に行うことができます。
- Navigation Timing API のアプローチでは、リアルユーザー モニタリング(RUM)指標がキャプチャされます。その名が示すように、これらの指標はサイトと実際のユーザー インタラクションから取得され、さまざまなデバイスやネットワーク条件でユーザーが経験する実際の CRP パフォーマンスを正確に把握します。
一般に、Lighthouse を使用して明らかな CRP 最適化の機会を特定し、Navigation Timing API でコードを計測可能にして、実際のアプリのパフォーマンスをモニタリングすることをおすすめします。
Lighthouse を使用したページの監査
Lighthouse は、特定のページに対して一連のテストを実行し、ページの結果を統合レポートに表示するウェブアプリ監査ツールです。Lighthouse は、Chrome 拡張機能または NPM モジュールとして実行できます。これは、Lighthouse を継続的インテグレーション システムと統合する場合に役立ちます。
はじめに、Lighthouse を使用したウェブアプリの監査をご覧ください。
Lighthouse を Chrome 拡張機能として実行すると、ページの CRP 結果は次のスクリーンショットのようになります。
この監査の結果の詳細については、重要なリクエスト チェーンをご覧ください。
Navigation Timing API を使用してコードをインストルメント化する
Navigation Timing API と、ページの読み込み時に発行されるその他のブラウザ イベントを組み合わせることで、任意のページの実際の CRP パフォーマンスをキャプチャして記録できます。
上の図の各ラベルは、ブラウザが読み込む各ページについて追跡する高解像度のタイムスタンプに対応しています。実際、この特定のケースでは、すべての異なるタイムスタンプの一部のみを表示しています。今のところ、ネットワーク関連のタイムスタンプはすべてスキップしますが、今後のレッスンで振り返ります。
では、これらのタイムスタンプは何を意味しているのでしょうか。
domLoading
: プロセス全体の開始タイムスタンプです。ブラウザは HTML ドキュメントの最初の受信バイトの解析を開始しようとしています。domInteractive
: ブラウザが HTML の解析をすべて終了し、DOM 構築が完了した時点を示します。domContentLoaded
: DOM の準備が整い、JavaScript の実行をブロックしているスタイルシートがない時点を示します。つまり、レンダリング ツリーを(おそらく)構築できる段階です。- 多くの JavaScript フレームワークは、独自のロジックの実行を開始する前に、このイベントを待機します。このため、ブラウザは
EventStart
タイムスタンプとEventEnd
タイムスタンプをキャプチャして、この実行にかかる時間を追跡できます。
- 多くの JavaScript フレームワークは、独自のロジックの実行を開始する前に、このイベントを待機します。このため、ブラウザは
domComplete
: その名のとおり、すべての処理が完了し、ページ上のすべてのリソース(画像など)のダウンロードが終了しました。つまり、読み込みスピナーの回転が停止しました。loadEvent
: 各ページの読み込みの最後のステップとして、ブラウザはonload
イベントを呼び出します。これにより、追加のアプリケーション ロジックがトリガーされます。
HTML 仕様では、すべてのイベントについて、いつ発生するべきか、どの条件を満たすべきかといった特定の条件が規定されています。ここでは、クリティカル レンダリング パスに関連するいくつかの重要なマイルストーンに焦点を当てます。
domInteractive
は、DOM の準備ができた時点を示します。domContentLoaded
は通常、DOM と CSSOM の両方が準備完了になった状態をマークします。- パーサーをブロックする JavaScript がない場合、
DOMContentLoaded
はdomInteractive
の直後に呼び出されます。
- パーサーをブロックする JavaScript がない場合、
domComplete
は、ページとそのすべてのサブリソースの準備ができたタイミングをマークします。
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
<script>
function measureCRP() {
var t = window.performance.timing,
interactive = t.domInteractive - t.domLoading,
dcl = t.domContentLoadedEventStart - t.domLoading,
complete = t.domComplete - t.domLoading;
var stats = document.createElement('p');
stats.textContent =
'interactive: ' +
interactive +
'ms, ' +
'dcl: ' +
dcl +
'ms, complete: ' +
complete +
'ms';
document.body.appendChild(stats);
}
</script>
</head>
<body onload="measureCRP()">
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
上記の例は、一見すると少し気が遠くなるように見えますが、実際には非常にシンプルです。Navigation Timing API は、関連するすべてのタイムスタンプをキャプチャし、コードは単に onload
イベントが発生するのを待ちます(onload
イベントは domInteractive
、domContentLoaded
、domComplete
の後に発生することを思い出してください)、さまざまなタイムスタンプの差を計算します。
これで、追跡する特定のマイルストーンと、これらの測定値を出力するシンプルな関数ができました。これらの指標をページに出力する代わりに、コードを修正して分析サーバーに送信することもできます(Google アナリティクスではこの処理が自動的に行われます)。これにより、ページのパフォーマンスを把握し、最適化作業によるメリットがある候補ページを特定できます。
DevTools についてはどうですか?
これらのドキュメントでは Chrome DevTools の [Network] パネルを使用して CRP のコンセプトを説明することがありますが、DevTools には重要なリソースを分離するメカニズムが組み込まれていないため、現時点では CRP 測定には適していません。Lighthouse 監査を実行して、このようなリソースを特定します。