ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

HTML5で Speed Test, Navigation Timing APIによる性能データ収集

今日は、HTML5 Advent Calendar 2011 9日目です。
何を書こうかネタに迷い、ひたすらHTML5のマイナーなAPIをあさっておりました。
FullScreen API/Page Visibility API も既に 登場してしまい、 @sada_h さんから Quota Management API はいかがとお奨めを受けましたがさすがに Quota管理だけでネタを展開するのは辛く、途方に暮れていました。
そんな折、ふと見かけたのが「Navigation Timing API」。マイナーだと思いますねぁ。今回このAPIの紹介とデモをさせていただきます。

Navigation Timing API

「いったい Navigation Timing API は何をするAPIか? 」単純です。
ブラウザーがWebの画面を表示する時にどこにどれだけ時間がかかているか知るAPIです。
ブラウザで画面が表示されるまではいくつかの段階に分かれています。大雑把に分類すると、DNSを引いてサーバのIPアドレスを取得したり、ネットワークの接続処理をする時間や実際にHTMLデータをやり取りする時間・そして描画を行う時間などです。
Navigation Timing API はそれらブラウザー内部で行われいる細かい処理が変わるタイミングでその時刻を記録しておいて性能評価やチューニングに生かそうというAPIです。
現在(2011年12月) When can I use Navigation Timing API?を見ると Chrome6以上/FireFox4以上/IE9以上/Android4 以上で利用できるAPIです。HTML5関連APIの中でも比較的広範囲にサポートされているAPIですね。
使うのは簡単。ブラウザー上で F12 を押して JavaScript コンソールを開きましょう。そこで window.performance と打って出てくるオブジェクトがそれ(時刻のデータが入ったオブジェクト)です。操作するメソッドやコールバックも何もいりません。ただオブジェクトのプロパティに値が入っているだけです。
Navigate Timing APIの中身の説明に入りますが、このAPIで得られる window.performance オブジェクトは大きく navigation と timing の2つのプロパティを持っています。

window.performance.navigation

windows.performance.navigation には、このページにどうやって来たのかという情報が保存されています。
windows.performance.navigation.typeの値は、

  1. 1 :リロードを行ってページを読み込んだことを示す。
  2. 2 :ブラウザーの進む・戻るといったヒストリー情報を使ってページを読み込んだ場合。
  3. 0 :それ以外の場合、例えばクリックや直接URLを打ち込んだりしてページにたどり着いた場合。

これらの操作の違いでページの表示速度は大きく変わりますので性能値を評価する場合には、ちゃんと区別することが必要ということだと思われます。

window.performance.timing

このオブジェクトには、実際の性能評価を行うタイミング項目での時刻(エポックタイム)が格納されています。数が多いので全ての説明はしませんが、それぞれのプロセスの開始と終了のタイミングに名前がついており、それらを引き算することでミリ秒のオーダーで処理時間を評価することができます。
W3CNavigation Timing API仕様の図を拝借するとわかりやすいです。
(図はW3C仕様から引用)
上記の図から大雑把に大きく、

  1. DNS : DNSサーバからIPアドレスを取得する時間
  2. TCP : WebサーバとのTCP接続が処理が完了するまで時間
  3. HTTP(Request+Response): Webサーバと HTTP のリクエスト・レスポンス処理にかかる時間
  4. DOM(Processing):ブラウザでDOMの構築処理を行っている時間
  5. Load(onLoad): windowが documentを読み込む onload イベントが行われている時間

にわけれます。

さぁ、早速見てみよう。

ここのサイト、
http://html5.ohtsu.org/html5advent2011/
で、Navigation Timing APIからブラウザ処理時間を見るデモサイトを作りました。
表示はこのような感じです。

リンクを戻ったり、リロードしたり、直接アクセスしたり、ラウザー変えて試したりすると、どのようなところでどう処理時間が変わっているのか見えて面白いかと思います。

今回表示がシンプルなコンテンツなのであまりバリエーションがないですが、うまくサイトを作るとHTML5だけで Speed Test のようなこともできるかと思います。

性能データを収集・表示へ

先程のデモでユーザからはこのサイトを見たらどれだけ処理に時間がかかっているかということがわかりましたが、今度はサーバ管理者の立場で考えるとすると自分のサイトにアクセスしてくるユーザがどれだけ処理に時間がかかっているか気になるでしょう。
自分が管理するWebサイトを最高にチューニングできるようユーザのブラウザー処理時間を細かく取得できるのは意味のあることです。そこで下記のような仕組みのアプリを作りました。

Node.js サーバではユーザがコンテンツを表示するトータルの時間と navigation タイプを取得しています。それを統計情報としてリアルタイムに表示することが可能です。
(注: Joyent の no.de サービス提供の終了に伴い下記サービスを停止しました。)
実際に動作するサーバは、
http://shigeki.no.de
で稼働しています。(ブラウザ表示のトータルの時間と navigation タイプ以外は取得していません。12月中程度はこのまま稼働しておきます。)
上記にアクセスすると、

のような統計情報が見られます。このページにアクセスした過去のユーザの表示時間の分布をリアルタイムで見ることができます。

まとめ

このように性能情報を取得し、細かいチューニングを行いより快適な環境をユーザに提供していく運用が、今後ますます重要になってくるものと思われます。
他に英文の記事として、HTML5RocksのMeasuring Page Load Speed with Navigation Timingが非常に参考になります。ここで紹介されている著者が作成した Chrome Extension Page Speed Testを使うと過去閲覧したサイトの性能値が Web SQL でローカルに保管され時系列でどう変わっているかグラフで見ることができます。一度お試しください。