クリティカル レンダリング パスを測定する

公開日: 2014 年 3 月 31 日

優れたパフォーマンス戦略の基盤となるのは、適切な測定と計測です。測定できないものは最適化できません。このガイドでは、クリティカル レンダリング パス(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 と、ページの読み込み時に発生する他のブラウザ イベントを組み合わせることで、任意のページの実際の CRP パフォーマンスをキャプチャして記録できます。

図の各ラベルは、ブラウザが読み込むすべてのページについて追跡する高解像度のタイムスタンプに対応しています。この図では、ネットワーク関連のタイムスタンプはすべて省略されています。

では、これらのタイムスタンプは何を意味するのでしょうか?

  • domLoading: プロセス全体の開始タイムスタンプ。ブラウザが HTML ドキュメントの最初に受信したバイトの解析を開始しようとしています。
  • domInteractive: ブラウザがすべての HTML の解析を完了し、DOM の構築が完了した時点をマークします。
  • domContentLoaded: DOM の準備が整い、JavaScript の実行をブロックするスタイルシートがない時点を示します。つまり、レンダリング ツリーを(潜在的に)構築できるようになりました。
    • 多くの JavaScript フレームワークは、このイベントを待ってから独自のロジックの実行を開始します。そのため、ブラウザは EventStartEventEnd のタイムスタンプを取得し、実行にかかった時間を追跡できるようにします。
  • domComplete: 名前が示すように、すべての処理が完了し、ページ上のすべてのリソース(画像など)のダウンロードが完了した状態です。つまり、読み込みスピナーの回転が止まった状態です。
  • loadEvent: ページ読み込みの最終ステップとして、ブラウザは onload イベントを発生させ、追加のアプリケーション ロジックをトリガーできます。

HTML 仕様では、各イベントの特定の条件(いつ発生させるか、どの条件を満たす必要があるかなど)が規定されています。

ここでは、CRP のいくつかの重要なマイルストーンに焦点を当てます。

  • domInteractive は DOM の準備が完了したタイミングを示します。
  • 通常、domContentLoadedDOM と CSSOM の両方の準備が完了したときにマークされます。
    • パーサーをブロックする JavaScript がない場合、DOMContentLoadeddomInteractive の直後に発火します。
  • 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 が関連するすべてのタイムスタンプを取得しています。コードは、domInteractivedomContentLoadeddomComplete の後に発生する onload イベントを待機します。その後、さまざまなタイムスタンプ間の差分を計算します。

これで、追跡する具体的なマイルストーンと、これらの測定値を出力する基本的な関数ができました。このコードを変更して、結果を出力する代わりに、これらの指標を分析サーバーに送信できます。これにより、ページのパフォーマンスを追跡し、最適化によって改善できるページを特定できます。

DevTools について

このドキュメントでは、CRP のコンセプトを説明するために Chrome DevTools の [Network] パネルを使用することがありますが、DevTools には重要なリソースを分離する組み込みのメカニズムがないため、CRP の測定には適していません。Lighthouse 監査を実行して、このようなリソースを特定します。