AJAXサイトの定期観測向け性能計測ツールを作ってみた
AJAXサイトの定期観測向け性能計測ツールを作ってみましたよ。
- ページの読み込み時間、サーバーAPIの呼び出し時間ならJMeter、JavaScriptの実行時間ならBenchmark.jsで計測できるけど、
- これらをひっくるめた読み込みを開始してから画面に情報が表示されるまでにかかる一連の時間を計測するツールとなるとFireBugくらいしか見当らないなー・・・。
- FireBugでも計測はできるけど、計測対象ページがいっぱいあったり、5回計測して平均をとる、とかいう場合にはちょいシンドイ。
- FireBug自体のオーバーヘッドも若干気になるし・・。
- あと、IE7,8でも測らんといかんので、同じ仕組みでIEでもFireFoxでも計測できるようにしておきたい。
というのが経緯。「ログ出力監視方式」の計測ツールならこれらの要件を満たせそう && 割とさくっと作れそうじゃね?と思い立って作ってみました。
仕組みと機能
- 計測対象のサイトをインラインフレーム内に読み込んで、あらかじめ仕込んでおいたログが出力されるまでの時間を計測するという仕組みです。
- ○ページの読み込み時間から、サーバーAPIの呼び出し時間、JavaScriptの実行時間を含めた読み込みを開始してから画面に情報が表示されるまでにかかる一連の時間を計測できます。
- ○特定のブラウザに依存しません。IE、Firefoxそれぞれの計測を同じツールで行えます。(原理的には)
- ×計測対象ページにあらかじめログ出力コードを埋めておく必要があります。
- ×iframeへのロードが禁止されていると計測できません。
- 計測対象のページや計測内容は、JavaScripで定義する方式です。
- 複数のテストを定義しておいて、まとめて実行できます。
- 指定された回数実行して平均、最大、最小を表示する機能もご用意。
-
- まぁ、必要ですよね。
-
プロファイラ的な使い方も無理すればできますが、それはFireBugやIEのデバッグツールを使ったほうが便利。
- そこそこページの多いサイトを作っていて、
- 各ページの表示性能を定期的に一括計測できるようにしておきたい!
という場合向きです。
ダウンロード
ファイル数が若干多いので、Google Codeに置いてます。
→perfjs - Download
使い方
概要は以下。
1.プロジェクトに計測ツール一式を取り込む
ダウンロードしたzipに含まれるフィルのうち、以下をプロジェクトに取り込みます。
- html/**
- css/**
- lib/**
配置場所は、HTTPで公開される場所であればどこでもOKです。
2.計測対象ページにログを埋め込む。
次に、計測対象とするページにログを埋め込みます。
- lib/perf-logger.jsにロガーの実装があるので、計測対象ページでこれを読み込んで、
- 「perf.logger.executed("<イベントID>");」を計測ポイントに入れていきます。
// ログを出力。 perf.logger.executed("test"); // "test-<NO>"を記録。 // <NO>はイベントの識別用番号で、イベントごとに1から順に採番されます。 // 一定の期間を計測するユーティリティもあります。 var end = perf.logger.start("test"); // "start-test-<NO>"を記録。 setTimeout( function() { end(); // "end-test-<NO>"を記録 }, 1000);
「perf.logger.*」はデフォルトでは何も実行しない空関数なので、実行しても何も起こりません。ページがiframeに読み込まれた際に、ツールによって上書きされます。
3.テストスクリプトを書く
ログを仕込んだら、次にテストスクリプトを用意します。「samples/script.js」にサンプルがあるので参考に。
// テスト定義 // 「../samples/test1.html」 を読み込んでdocument.onloadが呼ばれるまでの時間を計測する簡単なもの。 perf.regist({ // テストの識別用ID id : "test1", // 計測対象とする一連の処理。これの開始と終了までの所要時間が計測されます。 test: [ // 「../samples/test1.html」を読み込む。 perf.ops.load( "../samples/test1.html" ), // 「loaded-1」が出力されるまで待機する。 // 「loaded」イベントは出力コードを書かなくても、document.onloadのタイミンクで自動で記録されます。 perf.ops.wait( perf.exps.logged( "loaded-1" )) ] }); // 「../samples/test3.html」を読み込んで、ページで定義されているグローバル関数「log」を実行し、処理が完了するまでを計測するサンプル。 perf.regist({ id : "test3. サイトの関数を実行", // 前準備として実行する一連の処理。 // testと違ってこちらの所要時間は計測範囲に含まれません。 // また、後始末としてteardownも定義できます。 setup: [ perf.ops.load( "../samples/test3.html" ), // 「../samples/test3.html」を読み込み perf.ops.wait( perf.exps.logged( "loaded-1" )) // 読み込み完了を待つ ], test: [ // 「../samples/test3.html」のグローバル関数「log」x3を実行。 perf.ops.call( function( global ) { global.log( "a" ); setTimeout( function(){ global.log( "b" ); }, 200); setTimeout( function(){ global.log( "c" ); }, 500); }), // グローバル関数「log」の処理完了を示すログがすべて出力されるのを待機する。 perf.ops.wait( perf.exps.all( perf.exps.logged( "end-a-1" ), perf.exps.logged( "end-b-1" ), perf.exps.logged( "end-c-1" ) )) ] });
作成が完了したら、「./html/index.html」でスクリプトをロードする設定を行ってください。
... (略) <script type="text/javascript" src="../samples/scripts.js"></script>
4. index.html にアクセス。
あとは、アプリケーションサーバーなりWebサーバーなりを起動して、「./html/index.html」にアクセスすればOK。
・・・
やや突貫工事だったりするのでUIとかいろいろショボイですが・・・。とりあえずこれでストップウォッチは回避できるかな。