今回の記事ではJavaScriptpのNavigation Timing APIを使用して、サイトのパフォーマンスを計測する方法について解説します。
Google DevToolsを使用すれば、多角的に分析結果を確認することができますが、計測を自動化できないという短所があります。
JavaScriptで計測用のコードを実装することで、サイトパフォーマンスの計測を自動化することができます。

概要

Navigation Timing APIでは、ブラウザがHTMLなどのリソースを取得してから実際に描画するまでの、各フェーズの処理時間を計測することができます。
具体的には、performance.timingオブジェクトとプロパティを使用して計測を行います。

プロパティとその役割

プロパティ項目
navigationStartナビゲーションの開始時
unloadEventStartunloadイベントの発火開始時
unloadEventEndunloadイベントの発火終了時
redirectStartリダイレクト開始時
redirectEndリダイレクト終了時
fetchStartAppCacheからのfetchの開始時
domainLookupStartドメイン名解決の開始時
domainLookupEndドメイン名解決の終了時
connectStartTCP接続の開始時
secureConnectionStartTLSトンネルの接続の開始時
connectEnd接続確立の完了時
requestStartHTTPリクエストの送信開始時
responseStartHTTPレスポンスの受信開始時
responseEndHTTPレスポンスの受信終了時
domLoadingサーバーから取得したリソースをもとにDOM構築(HTMLのパース)を開始したタイミング
domInteractiveDOM構築(HTMLのパース)が終了したタイミング
domContentLoadedEventStartDOMContentLoadedイベントの開始時
domContentLoadedEventEndDOMContentLoadedイベントの終了時
domCompleteページ上の全てのリソースの読み込みの完了時
loadEventStartloadイベント発火時
loadEventEndloadイベントの発火終了時

各プロパティが実行されるタイミング

各タイミングについて解説

ナビゲーションの開始(navigationStart)

WEBページにアクセスした際に、
新しくHTML、CSS、JS、画像などのリソースを読み込み、WEBページを描画する一連の動作のことです。
リンクのクリック、フォームの送信、戻る、進むの各動作で発生します。
この開始時のタイミングをnavigationStartプロパティを使用して取得することができます。

アンロード(unloadEventStart, unloadEventEnd)

現在表示しているWEBページのリソースを破棄し、次に表示させるWEBページの準備をすることです。
このunloadの一連の処理時間をunloadEventStart, unloadEventEndを使用して取得することができます。

キャッシュ確認(fetchStart)

一度読み込んだリソースはブラウザにキャッシュされます。
一度サイトにアクセスした場合、キャッシュを使用することで効率的にリソースを取得することができるため、表示速度を向上させることができます。
しかし計測の際には、キャッシュの影響は無効化しておく必要があります。

計測

それでは実際に、JavaScriptのコードを使用して計測してみます。
計測項目は、Chrome DevToolsのNetworkタブで計測できる下記の主要項目に限定しました。
また、計測時はキャッシュの影響を無効化するために、シークレットウィンドウで計測しております。

  • リダイレクトにかかる時間
  • ドメインの名前解決にかかる時間(DNS Lookup)
  • 接続の確率にかかる時間(Initial connection)
  • HTTPリクエストの送信から受信までの時間(Waiting (TTFB))
  • ドキュメントの解析時間

計測用コード

window.addEventListener('load', function() {
    setTimeout(function() {
        // Navigation Timing API
        const timing = performance.timing;
        // 全てのリソースの読み込みにかかる時間
        console.log('全てのリソースの読み込みにかかる時間 : ' + (timing.loadEventEnd - timing.navigationStart) + 'ms')
        // リダイレクトにかかる時間
        console.log('リダイレクトにかかる時間 : ' + (timing.redirectEnd - timing.redirectStart) + 'ms');
        // ドメインの名前解決にかかる時間(DNS Lookup)
        console.log('ドメインの名前解決にかかる時間 : ' + (timing.domainLookupEnd - timing.domainLookupStart) + 'ms');
        // 接続の確率にかかる時間(Initial connection)
        console.log('接続の確率にかかる時間 : ' + (timing.connectEnd - timing.connectStart) + 'ms');
        // HTTPリクエストの送信から受信までの時間(Waiting (TTFB))
        console.log('HTTPリクエストの送信から受信までの時間 : ' + (timing.responseEnd - timing.requestStart) + 'ms');
        // ドキュメントの解析時間
        console.log('ドキュメントの解析時間 : ' + (timing.domInteractive - timing.domLoading) + 'ms');
    }, 0);
});

計測結果

JSでの計測結果

Networkタブの計測結果

若干の数値の差はありますが、基本的には同様の値になっているので、正確に計測できていることがわかります。

全体のリソースの読み込み、表示まで2sなので、基準の1000msに到達するためには、改善が必要です…

参考記事 : Navigation Timing API