ハイパフォーマンス Web アプリケーションの構築更新日: 2010 年 3 月 10 日 James Senior (Microsoft Corporation) 免責事項このドキュメントに記載されている情報は、このドキュメントの発行時点におけるマイクロソフトの見解を反映したものです。マイクロソフトは市場の変化に対応する必要があるため、このドキュメントの内容に関する責任をマイクロソフトは問われないものとします。また、発行日以降に発表される情報の正確性を保証できません。 このホワイト ペーパーに記載された内容は情報提供のみを目的としており、明示、黙示または法律の規定に関わらず、これらの情報についてマイクロソフトはいかなる責任も負わないものとします。 お客様ご自身の責任において、適用されるすべての著作権関連法規に従ったご使用を願います。このドキュメントのいかなる部分も、米国 Microsoft Corporation の書面による許諾を受けることなく、その目的を問わず、どのような形態であっても、複製または譲渡することは禁じられています。ここでいう形態とは、複写や記録など、電子的な、または物理的なすべての手段を含みます。ただしこれは、著作権法上のお客様の権利を制限するものではありません。 マイクロソフトは、このドキュメントに記載されている内容に関し、特許、特許申請、商標、著作権、またはその他の無体財産権を有する場合があります。別途マイクロソフトのライセンス契約上に明示の規定のない限り、このドキュメントはこれらの特許、商標、著作権、またはその他の無体財産権に関する権利をお客様に許諾するものではありません。 ©2009 Microsoft Corporation. All rights reserved. Microsoft、Windows、および Windows ロゴは、米国 Microsoft グループの登録商標または商標です。 記載されている会社名、製品名には、各社の商標のものもあります。 目次
1. 概要今日の Web アプリケーションの多くは JavaScript をサポートすることで、サーバーとのデータ送受信回数を最小限に抑えて、エンド ユーザーがデスクトップ アプリケーションのような感覚で利用できるようにしています。JavaScript と Ajax の機能をアプリケーションに追加するとさまざまな利点が得られますが、開発上のいくつかの重要な原則を考慮して適用しないと、別のパフォーマンス上の問題が発生する可能性があります。当然ながら、ユーザーのニーズを満たす高性能なアプリケーションを構築するには、Ajax の開発技法と開発ツールを十分に理解しておくことが重要です。 ブラウザーは長年にわたって進化し続けてきましたが、JavaScript を使用して効率的なクライアント側機能を構築する際の原則は以前とほとんど変わっていません。ブラウザーがどのように JavaScript コードを読み込んで、ドキュメント オブジェクト モデル (DOM) ルックアップを実行するのかを理解することは、すべての Ajax 開発者が習得すべき重要なスキルです。開発上のいくつかの簡単なヒントを活用することで、クライアント側のメモリー消費量を削減し、Ajax アプリケーションの全体的なパフォーマンス向上を図ることができます。これらの開発ヒントとしては、document.getElementById ルックアップから返されたオブジェクトをキャッシュに格納すること、ループ処理で同じ関数を複数回呼び出す場合は関数ポインターを作成すること、プロパティにアクセスするメソッドの使用をできる限り避けること、スクリプト結合機能を使用することなどが挙げられます。JavaScript のパフォーマンス向上に役立つヒントについては、http://channel9.msdn.com/posts/gioker84/Application-Performance-with-IE8 (英語) を参照してください。 JavaScript アプリケーションと Ajax アプリケーションのパフォーマンスに適用されるルールを理解することも重要です。Ajax のパフォーマンス技法に関する草分け的存在の 1 人である Steve Souders 氏は、自著の『ハイ パフォーマンス Web サイト - 高速サイトを実現する 14 のルール』(High Performance Web Sites: Essential Knowledge for Front-End Engineers) で、従うべき重要な一連のルールを紹介しています。ここで紹介されている重要なルールとしては、HTTP 要求数を最小限に抑えること、コンテンツ配信ネットワーク (CDN) を使用すること、有効期限ヘッダーを追加すること、コンポーネントを GZip で圧縮すること、スクリプトをページの最下部に記述すること、JavaScript ファイルを小型化することなどがあります。これらのルールに従うことで、Ajax アプリケーションで最新のブラウザー機能を活用でき、ページの読み込み速度を速くすることができます。 このホワイト ペーパーでは、ASP.NET Ajax Library に焦点を当て、Ajax アプリケーションのパフォーマンス向上に役立つ各種の開発ルール、開発技法、および開発ツールを紹介します。扱うトピックとしては、ASP.NET Ajax コンテンツ配信ネットワーク (CDN) によるスクリプトの高速読み込み、ASP.NET Ajax Library の Script Loader による複数スクリプトの並行読み込み、遅延読み込み技法によるバックグラウンドでのスクリプト読み込みなどがあります。また、Ajax アプリケーションのパフォーマンス向上を実現する IIS 7 の圧縮とキャッシュの設定について説明し、同時に Ajax アプリケーションのパフォーマンスに関連する各種のツールと技法も紹介します。 2. Microsoft Ajax コンテンツ配信ネットワーク (CDN)コンテンツ配信ネットワーク (CDN) は、世界中のアプリケーションで利用されるオーディオ ファイル、ビデオ ファイル、およびイメージ ファイルを配信する手段として幅広く使用されています。CDN は、配信するメディアのコピーを格納したサーバーのネットワークで構成されています。これらのサーバーは、最大限の帯域幅でクライアントがメディアに高速でアクセスできるように、世界中の戦略的なネットワーク ポイントに配置されています。 CDN は、メディア ファイルのストリーミングに使用されるだけでなく、読み込み時間の短縮やキャッシュ機能の強化などの重要なパフォーマンス上の利点を Ajax アプリケーションにもたらす JavaScript ファイルの配信にも使用されています。Microsoft Ajax CDN は、世界中の戦略的な場所に "エッジ キャッシュ" サーバーを配置することで、Ajax アプリケーションによるスクリプトの読み込み効率向上を実現する無償サービスです。Microsoft Ajax CDN を使用すると、何回ものホップを介してホスト元のサーバー (別の大陸に設置されていることもあります) からスクリプトを取得する代わりに、ネットワーク間の最少ホップ数でスクリプトをすばやく読み込むことができます。次に示すパフォーマンス例は CDN のパフォーマンスの概要を示したものですが、厳密なテスト手法に基づくものではなく、あくまでも全体像を示すことを目的としています。 表 1 では、米国に設置された 1 台の共有ホスト サーバーから ASP.NET Ajax スクリプトをダウンロードする場合と、同じスクリプトを Microsoft Ajax CDN からダウンロードする場合とで、その所要時間を比較しています。
表 1: 共有ホスト環境でホストされているスクリプトと Microsoft Ajax CDN 上でホストされているスクリプトの読み込み時間の比較 表 1 の "No CDN"(CDN 使用せず) と示された結果は、米国内の共有ホスト サーバーに置いた Web ページを対象とした実行結果であり、スクリプトは同じサーバーから取得しています。"CDN"(CDN 使用) と示された結果は、同じ共有ホスト サーバー上のページを対象としたものですが、スクリプトは Microsoft CDN から取得しています。表 1 に示す取得時間は、テストの実行場所と実行時刻、使用するコンピューターの種類、使用可能な帯域幅、および呼び出す共有ホスト サーバーに応じて当然ながら変化します。しかし、これらの変動要素を考慮に入れたとしても、CDN がパフォーマンスの向上をもたらすことは明らかです。 スクリプトの取得時間は、そのスクリプトに到達するために要するネットワーク ホップ数などのさまざまな要素によって左右されます。ネットワークによっては内部ホップを持つものがあるので、ネットワーク ホップ数が多いからといって、必ずしも低速なルートをたどっているわけではありませんが、メッセージがクライアントの間を移動している様子はこれでもわかります。表 2 では、共有ホスト サーバーを呼び出す場合と、Microsoft Ajax CDN からスクリプトを取得する場合のネットワーク ホップ数を比較しています。
表 2: JavaScript アプリケーションで使用するスクリプトを取得するために必要なネットワーク ホップ数 ネットワーク ホップ間で要する時間も、全体的なパフォーマンス計算式に算入できます。図 1 は、共有ホスト サーバーと Microsoft Ajax CDN に対して実行した簡単な tracert コマンドの例を示しています。この結果から、CDN の各セグメントのパフォーマンスがたいへん優れていることがわかります。 共有ホスト サーバーまでのルートのトレース
Microsoft Ajax CDN までのルートのトレース
図 1: 共有ホスト サーバーを呼び出す場合と Microsoft Ajax CDN を使用する場合のネットワーク ホップ速度の比較 スクリプトの読み込み時間は、キャッシュを使用することでさらに短縮できます。複数の Ajax アプリケーションで Microsoft Ajax CDN ファイルを参照している場合、読み込んだスクリプトはクライアント ブラウザーでキャッシュに格納され、再利用されます。たとえば、Microsoft Ajax CDN を使用してスクリプトを読み込む contoso.com ドメイン上のアプリケーションにクライアントがアクセスすると、これらのスクリプトはすべてローカルでキャッシュに格納されます。同様に CDN を使用する xyz.com ドメインにこのクライアントがアクセスすると、キャッシュに格納されたスクリプトが再利用されます。Microsoft Ajax CDN を利用するすべてのアプリケーションでは、開発段階で特別な操作をしなくても、キャッシュを使用することによるこの利点が得られます。訪問者数が何百万人にものぼるさまざまな Microsoft の Web サイトでも CDN の使用を予定しています。これにより、世界中の多くのブラウザーは Microsoft Ajax CDN からスクリプトを入手し、キャッシュに格納して利用できるようになります。 a. ASP.NET Ajax スクリプトの読み込みMicrosoft Ajax CDN は、さまざまなスクリプトを http://ajax.microsoft.com ドメインでホストしています。このようなスクリプトとして、ASP.NET Ajax スクリプトや jQuery スクリプトがあります。Microsoft Ajax CDN のスクリプトにアクセスするには、次のように Ajax.microsoft.com を参照する標準の script タグをページに記述します。 この script タグで指定した URI の 0911 で、読み込むスクリプトのバージョンを指定するので、CDN を使用すればアクセスごとに異なるバージョンのスクリプトをホストできます。その結果、新しいバージョンのスクリプトがリリースされても旧バージョンを保持できるので、その後も既存のアプリケーションを引き続き使用できます。ASP.NET Ajax スクリプト ライブラリでサポートされているスクリプトはすべて CDN から利用できます。このようなスクリプトには、MicrosoftAjax.js、MicrosoftAjaxDataContext.js、MicrosoftAjaxTemplates.js、MicrosoftAjaxWebForms.js、Start.js などの多用するスクリプトもあります。 Microsoft Ajax CDN のスクリプトは、ASP.NET 4 の ScriptManager コントロールで自動的に読み込むこともできます。ASP.NET 4 では、EnableCdn という新しいプロパティが ScriptManager に追加されています。このプロパティを使用すると、パフォーマンスの向上とキャッシュの活用を目的として、アプリケーションのホスト サーバーからではなく Microsoft Ajax CDN からスクリプトを読み込むことができます。 Microsoft Ajax CDN にはデバッグ バージョンのスクリプトも用意されています。デバッグ バージョンのスクリプトが役に立つのは、読みやすい形式でのコードの表示、Visual Studio を使用したコードのステップ実行、Internet Explorer 8 を使用したスクリプトのデバッグなどを開発段階で行う場合です。デバッグ バージョンのスクリプトを読み込むには、次のようにスクリプト名の末尾に "debug" を追加します。 b. jQuery スクリプトの読み込みMicrosoft Ajax CDN を使用すると、次のように標準の jQuery ライブラリのほか、jQuery Validation Library などの jQuery スクリプトを読み込むこともできます。 使用可能な jQuery スクリプトの形式には、次のように完全バージョン、小型化バージョン、vsdoc バージョン (Visual Studio で IntelliSense に使用)、および小型化した vsdoc バージョンがあります。
使用可能な jQuery Validation Library スクリプトの形式は次のとおりです。
Microsoft Ajax CDN を使用すると、最小限のネットワーク ホップ数ですばやく効率的にスクリプトを読み込むことができます。CDN のスクリプトを使用するアプリケーションは、複数のドメインにわたってブラウザーのキャッシュ機能を利用し、不要なスクリプト読み込みを回避することもできます。CDN が提供するその他の利点としては、アプリケーション用に配置する必要のあるファイル数を削減できること、今後アプリケーションを拡張した場合でも複数のバージョンのスクリプトの取り扱いが容易であることなどが挙げられます。Microsoft Ajax CDN の詳細については、http://www.asp.net/ajaxlibrary/cdn.ashx (英語) を参照してください。 3. ASP.NET Ajax Library の Script LoaderJavaScript アプリケーションを読み込むために必要なスクリプトの数をできる限り減らすことは、ページの読み込み時間を短縮するための一般的な技法です。これにより、ページが表示されるまでエンド ユーザーを長時間待たせることがなくなります。ページの中で追加的に使用するスクリプトは、ページを最初に読み込むときに取得して実行するのではなく、必要に応じてバックグラウンドで取得し、必要になった時点で初めて実行するようにします。この技法は単純なプロセスのように見えますが、あるスクリプトを使用するためには、他のスクリプトを適切なタイミングと順序で読み込む必要がある場合は複雑なプロセスになる可能性があります。 以前のブラウザーでは、並行して読み込めるスクリプトは最大で 2 つのみで、このスクリプトを増やすには、document.write ステートメントや iframe を使用し、<script> ブロックをプログラムによって作成する動的スクリプト添付などのコーディング手法を別途使用する必要がありました。最新のブラウザーでは、複数のスクリプト (同じドメインから 3 つ以上) を並行して読み込むことでパフォーマンスの向上を図ることができます。当然ながら、複数のスクリプトを並行して読み込むと (図 2 を参照)、スクリプトを 1 つずつ読み込む際のボトルネックが解消されるため (図 3 を参照)、アプリケーションの読み込みを大幅に高速化できます。
図 2: 複数のスクリプトを並行して読み込むことで、アプリケーションの合計読み込み時間を短縮できますが、処理が複雑になることがあります。
図 3: スクリプトを 1 つずつ読み込むことがボトルネックとなり、アプリケーションの起動時間が長くなる可能性があります。 複数のスクリプトを並行して読み込むと、パフォーマンスは向上しますが、タイミングの問題が原因で最終的にアプリケーションで問題が発生する可能性があります。たとえば、スクリプト FooDependency.js に依存するスクリプト Foo.js を FooDependency.js と並行して読み込む場合、Foo.js を先に読み込んで実行しようとすると問題が発生する可能性があります。この問題を軽減するための解決策としては、複数のスクリプトを結合して 1 つのファイルにまとめる方法や、各スクリプトの onreadystatechange イベントを使用してそのスクリプトがダウンロードされたタイミングを確認する方法などが考えられます。 これらの解決策で問題に対処することもできますが、ここでは Script Loader フレームワークの使用をお勧めします。Script Loader は各種のブラウザーに対応しており、柔軟性があって再利用可能なうえ、容易に入手できます。ASP.NET Ajax Library が提供する堅牢な Script Loader を使用すると、アプリケーションを開始するために必要なスクリプトの数を最少化し、他の必要なスクリプトやこれらの依存関係の並行読み込みを処理できます。また、スクリプトの並行読み込みに伴うタイミング問題も単純化できます。これらのすべての機能が、11 KB にすぎないサイズのスクリプト Start.js にパッケージ化されています。 表 3 は、<script> 要素を使用して指定の 5 つのスクリプトを読み込むページと、Script Loader を使用して同じ 5 つのスクリプトを読み込むページの読み込み時間を比較しています (Script Loader では Start.js スクリプトを使用するので、ページに読み込むスクリプトの合計数は 6 つになります)。
表 3: 従来の <script> 要素を使用する場合と Script Loader を使用する場合のページ読み込み時間の比較 このテストで読み込んでいるスクリプトの数はわずか数個であるにもかかわらず、Script Loader を使用するページの読み込み時間は 0.5 秒短縮されていることがわかります。読み込むスクリプトの数が増えるにつれて、これら 2 つの方法の間に発生するページ読み込み時間の差はさらに広がります。1 番目のページ (読み込み時間は 1.6 秒) ではスクリプトは次のように定義されています。 2 番目のページ (読み込み時間は 1.1 秒) では、次のように Script Loader を使用して同じスクリプトを読み込んでいます。 次のセクションでは、Script Loader を使用して ASP.NET Ajax Library スクリプト、jQuery スクリプト、およびカスタム スクリプトを読み込む方法の詳細と例を示します。 a. ASP.NET Ajax Script Loader の使用Start.js という Script Loader は、アプリケーションで必要な ASP.NET Ajax Library スクリプト、jQuery スクリプト、およびカスタム スクリプトの読み込みを標準でサポートしています。Start.js は、次のようにローカル サーバーまたは Microsoft Ajax CDN から読み込むことができます。 Start.js をローカル パスから読み込んだ場合、Start.js は、同様にローカル パスに格納されている所要の ASP.NET Ajax Library スクリプトを検索します。CDN バージョンの Start.js を使用すると、Start.js は ASP.NET Ajax Library スクリプトと jQuery スクリプトを CDN から取得するので、ネットワーク パフォーマンスが向上し、キャッシュ機能を活用できるようになります。 ページで Start.js を定義しておくと、アプリケーションで使用する ASP.NET Ajax Library スクリプト、jQuery スクリプト、およびカスタム スクリプトを Start.js で読み込むことができます。続いて Sys.require を使用し、必要なアプリケーション スクリプトを読み込むことができます。Sys.require には 3 つのパラメーターを指定できます。それは、読み込むコンポーネントとスクリプトが格納された配列、これらのスクリプトの準備ができたときに実行するコールバック関数、およびステート情報を渡すためのユーザー コンテキスト オブジェクトです。次の例では、必要なコンポーネントとスクリプトの配列を Sys.require に渡しています。 Script Loader では必要な複数のスクリプトを並行して取得します。これらのスクリプトに関連付けられたオブジェクトと関数は、onReady を呼び出せば使用できます。別の方法として、次のように Sys.require に指定できる 2 つ目のパラメーターを使用して、必要なスクリプトが読み込まれて DOM の準備ができたときに実行する処理を指定できます。 表 4 は、組み込みの Sys.scripts コレクション メンバーと、ASP.NET Ajax Library の中でこれらのメンバーが関連付けられたスクリプトを示しています。図 4 は、ASP.NET Ajax Library スクリプト間の関係を示しています。
表 4: ASP.NET Ajax Library の Script Loader を使用して必要なスクリプトを読み込むために使用できる Sys.scripts メンバー
図 4 : ASP.NET Ajax Library スクリプトとそれらの依存関係 Script Loader は、必要なスクリプトと依存関係の読み込みを自動的に処理すると共に、同じスクリプトが複数回読み込まれないようにするメカニズムも標準で備えています。Sys.require ([Sys.scripts.DataContext]) という値を Script Loader に渡すと、MicrosoftAjaxDataContext.js のほか、MicrosoftAjaxComponentModel.js、MicrosoftAjaxSerialization.js、MicrosoftAjaxWebServices.js、および MicrosoftAjaxAdoNet.js の 4 つの各スクリプトの読み込みがバックグラウンドで処理されます。この結果として、ページを実行するために必要なコードの量を削減でき、さらにスクリプト ファイルとそれらの依存関係の並行読み込みを管理することに伴う複雑さも軽減できます。これらのスクリプトは、別のスクリプトで必要な場合でも 1 回だけ読み込まれます。 Sys.require を使用すると、アプリケーションで使用するコンポーネントと、それらのスクリプトの依存関係も読み込むことができます。組み込み値としては、adoNetDataContext、adoNetServiceProxy、dataContext、dataView などがあります。Sys.require に値 Sys.components.dataView を渡すと、DataView オブジェクトをサポートしているスクリプトが自動的に読み込まれます。DataView コンポーネントを参照したときに読み込まれるスクリプトは、Internet Explorer 8 開発者ツールなどを使用して確認できます (図 5 を参照)。
図 5: Script Loader を使用して DataView コンポーネントを読み込んだときに読み込まれるスクリプト b. カスタム スクリプトの読み込みASP.NET Ajax Library の Script Loader が特に役立つのは、アプリケーションで使用するカスタム スクリプトとその関連する依存関係を読み込む場合です。Script Loader を使用すると、デバッグ バージョンとリリース バージョンの両方のスクリプトを読み込むことができるほか、適切なタイミングで依存関係も自動的に読み込まれます。カスタム スクリプトを読み込むには、Sys.loader.defineScripts 関数を呼び出します。次の例では、リリース バージョンとデバッグ バージョンの URL とその依存関係を Sys.loader.defineScripts に渡しています。 この例では、ACTWatermark.js (Ajax Control Toolkit で提供されているクライアント側コンポーネント)、ACTExtenderBase.js、および ACTCommon.js の各スクリプトを適切な順序で読み込んでいます。各スクリプトを読み込むために使用する releaseUrl および debugUrl のパスをまず定義した後で、読み込む必要のあるカスタム スクリプトを列挙しています。それぞれのスクリプト定義では、releaseUrl プロパティまたは debugUrl プロパティに適宜関連付ける名前、依存関係の配列、コントロール用としてスクリプトで使用できる動作のうち使用する必要がある動作を指定しています。また、スクリプトが読み込まれたことを確認する処理も記述しています (この確認処理により、同じスクリプトが複数回読み込まれないようにすることができます)。 最後の ACTCommon スクリプトは、ASP.NET Ajax Library (または jQuery) の依存関係を追加的に読み込む際に Script Loader が発揮する柔軟性を示しています。ACTCommon を実行時に使用するには、その前に MicrosoftAjaxComponentModel.js と MicrosoftAjax.Globalization.js を読み込んでおく必要があることを、ACTCommon の executionDependencies プロパティで指定しています。 さまざまなスクリプトを使用するには、JavaScript 定義ファイル (次の例では ACTRegisterExtended.js) のパスをページに記述しておき、必要なコンポーネントを参照します。この例では、ACTWatermark スクリプトで指定した Watermark コンポーネントを使用しています。 c. スクリプト結合Script Loader では、スクリプトとそれらの依存関係を読み込むだけでなく、スクリプト結合機能を利用して、サーバーに対するネットワーク呼び出しの回数を削減することもできます。これはもう 1 つの重要なパフォーマンス上の利点です。この機能を使用すると、すべての ASP.NET Ajax Library スクリプトを個別に読み込むのではなく、単一のスクリプトを必要に応じて読み込むことができます。たとえば、次の Sys.require 構文を使用すると、7 つの個別のスクリプトではなく、MicrosoftAjax.js というスクリプトがサーバーから取得されます。 Script Loader では、スクリプトを結合するタイミングを判断する必要があります。まず、結合するスクリプトがサーバー上で使用できるようになっている必要があります。Script Loader はクライアント側のコンポーネントであるため、サーバー側のスクリプト結合を実行できません。しかし、"結合後" のスクリプトに存在するスクリプトを定義しておくことで、Script Loader でスクリプト結合機能を利用できます。上記のコード例では、Start.js にある "contains" 定義に基づいてサーバーから MicrosoftAjax.js を取得しています。Script Loader は、"contains" で指定されたすべてのスクリプトが必要と判断すると、スクリプト結合機能を自動的に利用します。カスタム スクリプトについても同じ技法を使用できます。 次のように 1 つのページに複数の Sys.require 呼び出しを追加すると、スクリプトが個別に読み込まれるので、スクリプト結合の利点は得られません。 d. デバッグ時の Script Loader の使用開発段階では、デバッグ バージョンの ASP.NET Ajax Library スクリプトとカスタム スクリプトを使用し、Visual Studio で IntelliSense を有効にしてデバッグ効率の向上を図ることが普通です。デバッグ バージョンのスクリプトは、サイズが大きく、パフォーマンス低下の原因となる可能性があるので、実稼働アプリケーションでの使用はお勧めできません。それでも、リリース バージョンのスクリプトとデバッグ バージョンのスクリプトを簡単に切り替えることができれば、さまざまな状況で便利です。 ASP.NET Ajax Library が提供する Sys.debug プロパティを使用すると、リリース バージョンとデバッグ バージョンのスクリプトをすばやく簡単に切り替えることができます。Script Loader に渡すスクリプトの名前を変更する代わりに、次のように Sys.debug の値を true に設定するだけで、Script Loader は名前の末尾が "debug.js" であるスクリプトを自動的に読み込むようになります。 図 6 は、Sys.debug を true に設定している場合に Script Loader によって読み込まれるスクリプトを示しています。また、図 7 は、false に設定している場合に読み込まれるスクリプトを示しています。
図 6: Sys.debug を true に設定すると、他のコードを変更しなくても、ASP.NET Ajax Library の Script Loader はデバッグ バージョンのスクリプトを自動的に読み込みます。
図 7: Sys.debug を false (既定値) に設定している場合に読み込まれるスクリプト デバッグ バージョンのスクリプトの場所を正しく定義しておけば、ASP.NET Ajax Library のスクリプト、カスタム スクリプト、および jQuery スクリプトでもこの手法を使用できます。Start.js では、ASP.NET Ajax Library スクリプトのリリース バージョンとデバッグ バージョンそれぞれのパスを次のコードで定義します。% 記号は、Start.js の場所を基準とした相対スクリプト パスであることを示します。 jQuery を使用する場合、Start.js では、小型化バージョンの jQuery がリリース バージョンのスクリプトとして使用され、書式整形バージョンがデバッグ バージョンとして使用されます。 web.config のデバッグ設定と同様に、アプリケーションを実動環境に移行する前に、Sys.debug の値を false (既定値) に変更する必要があります。これにより、アプリケーションに最大限のパフォーマンスを実現できます。このように変更しないと、読み込まれる JavaScript ファイルのサイズが大きくなるため、必然的にアプリケーションの読み込み時間が長くなります。 e. Script Loader の遅延読み込み機能を使用したパフォーマンスの向上多くの JavaScript アプリケーションでは、ページを最初に読み込んだ時点では直ちに必要ではない機能を使用しています。たとえば、ユーザーがページを印刷するためにクリックする印刷ボタンを備えているアプリケーションがあります。印刷ボタンがクリックされたときに実行するスクリプトは、エンド ユーザーによってページが操作されるまでは使用しないので、ページを最初に読み込むときに同時に読み込む必要はありません。このような場合は、ページを読み込んで表示した後でこのスクリプトを読み込むほうが合理的です。 ページを読み込んだ後でスクリプトを読み込む機能を "遅延読み込み" といいます。ページの初期表示に要する時間を大幅に短縮できるので、ユーザーはすぐにアプリケーションを操作できます。これまでも、各種の JavaScript フレームワークやカスタム コーディング技法を使用することでスクリプトの遅延読み込みは可能でしたが、ASP.NET Ajax Library の Script Loader では、スクリプトの遅延読み込みによるアプリケーションのパフォーマンス向上が大幅に容易になっています。 Script Loader は、Sys.require を使用した遅延読み込みを標準でサポートしています。前述の例では、Sys.require を使用して、ページの読み込みと同時にスクリプトとそれらの依存関係を読み込む方法を示しました。ページの読み込みと同時にスクリプトを読み込む必要がない場合でも、Sys.require を使用して、ユーザーがボタンのクリックなどの操作を実行した時点でスクリプトを遅延読み込みできます。次のコード例では、Script Loader の遅延読み込み機能を使用して、ユーザーがページを操作した時点で追加のスクリプトを取得する方法を示しています。このコード例の重要な部分は、Print 関数の中にあります。 ページを読み込むときには Start.js と RegisterPrintScripts.js のみをサーバーから取得するので、ページをすばやく読み込むことができます。[Print Page] ボタンのクリックによって Print 関数が呼び出されます。この関数では、Sys.require を使用して印刷スクリプトと関連するスクリプトをバックグラウンドで遅延読み込みします。印刷スクリプトとその依存関係を読み込むときに多少の遅延が発生しますが、読み込んだスクリプトはキャッシュに保存され、以降のこのページへのアクセスで再利用できます。したがって、この遅延が発生するのはこの読み込み時のみです。 Print 関数の中に Sys.require を記述すると、カスタムの Print.js スクリプトと必要な ASP.NET Ajax Library スクリプトは、Script Loader によってバックグラウンドで遅延読み込みされます。これらのスクリプトを取得すると Sys.onReady が呼び出され、印刷スクリプトを使用するコードが実行可能になります。Sys.onReady は、Print 関数で定義したスクリプトを読み込んだ後で初めて呼び出されます。この例では、Print 関数の中に Sys.onReady を記述しているので、ページを最初に読み込むときには Sys.onReady は呼び出されません。 4. JavaScript アプリケーションのパフォーマンス ツールAjax アプリケーションの開発段階では、Microsoft Ajax CDN や ASP.NET Ajax Library の Script Loader などのさまざまな機能を利用して、Ajax アプリケーションのパフォーマンス向上を図ることができます。ASP.NET Ajax Library の機能や以下で説明する推奨のコーディング手法のほかにも、Ajax アプリケーションのパフォーマンスの向上と解析で利用できるツールがいくつかあります。ここでは重要なパフォーマンス ツールとして、Download Time Optimizer (Doloto)、ASP.NET Ajax Minifier、Internet Explorer 8 JavaScript Profiler、およびインターネット インフォメーション サービス (IIS) 7 の GZip 圧縮機能を紹介します。 a. Download Time Optimizer (Doloto)JavaScript と Ajax の機能やクライアント側のデータ レンダリングをサポートするアプリケーションが増えるにつれて、アプリケーションを実行するためにブラウザーで読み込む必要のあるコード量は増大する傾向にあります。ページ読み込みの高速化やスクリプトの遅延読み込みを可能にする Script Loader などの強力な機能が ASP.NET Ajax Library に用意されていますが、コード読み込みの最適化では、Download Time Optimizer (Doloto) などのツールの役割が重要です。Doloto の Web サイト (http://research.microsoft.com/en-us/projects/doloto (英語)) には、このツールについて次のような説明があります。 "Doloto は、アプリケーションのワークロードを解析して、既存の大きな Web 2.0 アプリケーションのコードを自動的に分割するシステムです。Doloto で処理したアプリケーションからは、アプリケーションの初期化に必要な一部のコードのみが最初に転送されます。アプリケーションの残りのコードは短いスタブに置き換えられます。これらのスタブの実際の機能コードは、バックグラウンドで遅延転送されるか、遅くともそのコードを初めて実行するときに転送されます。" Doloto は 3 つの主なフェーズをたどります。1 番目のフェーズは、コードがどのように使用されているのかを定義する "アクセス プロファイル" を作成するトレーニング フェーズです。2 番目のフェーズは、オンデマンド コード読み込みに合わせてスクリプトを最適化する書き直しフェーズです。3 番目のフェーズは、アプリケーションの実行につれてスクリプトをバックグラウンドで読み込むプリフェッチ フェーズです。この最適化では、まず Web アプリケーションのコードがどのように使用されているかを解析し、続いてコード分割を実行して JavaScript 関数を "クラスター" にまとめ、前述の "アクセス プロファイル" を作成します。 Doloto を使用するには、そのプログラムを起動し、http://localhost:8888 を使用するようにブラウザーのプロキシを変更します。続いて、Doloto の [Profile] ボタンをクリックし、Doloto で調査するサイトにブラウザーからアクセスします。そのサイトで、Doloto はプロキシ ベースのコード プロファイリングを使用して、そのサイトの "アクセス プロファイル" を作成し、最適化した "クラスター" に JavaScript 関数をまとめます (図 8 を参照)。これらのクラスターを作成すると、最適化によって得られるサイズ削減の推定値を表示できます。同時に、既存の Web サイト スクリプトを書き直し、バックグラウンド読み込みに合わせて最適化した形式に変更できます。
図 8: http://www.bing.com/maps 向けに Doloto で作成したクラスター Live.com (現在は Bing.com) や Google Spreadsheets などのいくつかの大規模な Ajax サイトに対して Doloto を実行すると、読み込むスクリプトのサイズを 20 ~ 40% 削減できると共に、エンド ユーザーがアプリケーションの使用を開始できるまでの時間を短縮できます。図 9 は、Doloto をいくつかのサイトに対して実行した後のダウンロード サイズの減少率を示しています。
図 9: Doloto では、Ajax アプリケーションを実行するために事前に読み込むスクリプトの数を最小限に削減できます。この図は、Doloto による最適化を実行した後のダウンロード サイズの減少率を示しています。 b. Microsoft Ajax MinifierASP.NET Ajax Library のスクリプトには、デバッグ用の書式整形バージョンと実稼働アプリケーション用の小型化バージョンの 2 つの形式があります。ASP.NET Ajax Library スクリプトの小型化バージョンは、実稼働アプリケーションのパフォーマンス向上を実現する小型化ファイルとして提供されます (これは圧縮ファイルではありません)。これまでも Microsoft は社内ツールを使用してスクリプトを小型化してきましたが、このツールは現在、Microsoft Ajax Minifier として公開されています。このツールを使用すると、JavaScript ファイルから不要な内容を除去してそのサイズを削減できるので、アプリケーションでスクリプトをダウンロードする時間を短縮できます。 ajaxmin input.js -o output.js 上記のコマンドでは標準の小型化処理を実行できますが、次のように /H コマンド ライン スイッチを指定すると小型化の比率を大きくすることができます。 ajaxmin input.js -o output.js /H これ以外にもさまざまなコマンド ライン スイッチが用意されています。たとえば、Macintosh Safari の不具合に対処するコードを追加するための /M、小型化したストリームの末尾にセミコロンを付加するための /Z、出力ファイルのエンコード方式を定義するための /Eo があります。 コマンド ライン バージョンのほか、Microsoft Ajax Minifier には、カスタム .NET プログラムで使用できるアセンブリと、Visual Studio プロジェクトの構築時に小型化バージョンのスクリプトを自動的に作成できる MSBuild タスクも用意されています。このツールのヘルプ ドキュメントには、このアセンブリと MSBuild タスクをアプリケーションで使用するための手順ガイドが掲載されています。 次の例では、Microsoft Ajax Minifier を使用してスクリプトを小型化する方法を示しています。1 番目の例では書式整形バージョンのスクリプト、2 番目のコード例では小型化バージョンをそれぞれ示しています。小型化バージョンのすべてのコードは、生成された出力ファイルの中で 1 行に記述されています。 書式整形したスクリプト: 小型化したスクリプト: c. Internet Explorer JavaScript Profiler各種のブラウザーで高いパフォーマンスを発揮する最適なコードを記述するには、そのコードで実行する処理を詳しく調べる必要があります。幸い、Internet Explorer 8 で導入された開発者ツール機能を使用すると、HTML ソース コードの表示と調査、CSS の編集、JavaScript コードの表示、デバッグ、およびプロファイリングなどが可能です。IE 8 開発者ツールにある JavaScript Profiler ツールを使用すると、アプリケーションで関数が呼び出される様子、関数の実行にかかる時間、および関数が呼び出される回数を詳しく解析できます。 IE 8 JavaScript Profiler にアクセスするには、メニューから [ツール]、[開発者ツール] の順に選択するか、F12 キーを押します。このツールは、スタンドアロン ウィンドウ モードで開くことができるほか、既存のブラウザー ウィンドウで開くこともできます。このツールを開いて [プロファイラー] タブをクリックすると、JavaScript Profiler にアクセスできます。既存のアプリケーションをプロファイリングするには、[プロファイリングの開始] をクリックして、プロファイリングするページにアクセスします。そのページを読み込んで必要なテスト処理を実行した後、[プロファイリングの停止] ボタンをクリックして結果を表示します。図 10 は、IE 8 JavaScript Profiler の実際の画面例を示しています。
図 10: http://www.bing.com/maps サイトで実行し、JavaScript Profiler を使用して表示した呼び出し JavaScript Profiler のデータを読み込むと、各関数呼び出しに関する情報を表示して解析できます。たとえば、図 10 のデータからは、Init 関数が 18 回呼び出されたこと、およびコードの合計実行時間のうち 6.24% がこの関数とその子関数に費やされたことがわかります。各列を参照すると、コードの中で最適化の余地がある箇所や、パフォーマンス向上のために解消すべきボトルネックが存在する可能性のある箇所を簡単に特定できます。JavaScript Profiler では数種類のレポートを作成できるほか、このツールで作成したデータを CSV ファイルとしてエクスポートし、さらに詳しく解析できます。JavaScript Profiler を使用することで、JavaScript 呼び出しの流れを詳細に把握して、コードの調整やアプリケーションのパフォーマンス向上に役立てることができます。 d. Internet Information Server 7 の圧縮機能とキャッシュ機能インターネット インフォメーション サービス (IIS) に組み込まれた圧縮機能を使用してスクリプトやページを圧縮することで、これらをブラウザーに効率的に配信できます。HTTP 圧縮を使用すると、サーバー全体にわたって圧縮を適用できます。また、URL 圧縮を使用すると、より細かい単位で圧縮を適用できます。HTTP 圧縮は、applicationHost.config ファイルで定義するグローバル設定 (httpCompression 要素) です。また、URL 圧縮は、web.config レベル (urlCompression 要素) で構成して、特定のサイト、アプリケーション、またはフォルダーに適用できます。 Ajax アプリケーションに最大限のパフォーマンスを実現するには、CSS ファイル、JavaScript ファイル、HTML ファイルなどのコンテンツに GZip 圧縮を適用することをお勧めします。これによりデータを圧縮できるので、開発段階で余分なコードを記述しなくても、データのネットワーク伝送速度を速くすることができます。IIS 7 では、applicationHost.config ファイルで動的圧縮と静的圧縮の設定を定義します。図 11 に示すように、インターネット インフォメーション サービス マネージャーを使用してこれらの設定を有効または無効にできます。
図 11: インターネット インフォメーション サービス マネージャーを使用した IIS 7 の圧縮設定へのアクセス IIS 7 を使用して、次のようにテキスト、JavaScript、XAML、ATOM フィードなどのさまざまな種類のファイルを圧縮できます。 IIS 7 で JavaScript ファイルを目的どおりに圧縮できない場合は、その MIME タイプが原因であることが考えられます (http://www.fiddlertool.com などのツールを使用すると、サーバーから送信された Content-Type 応答ヘッダーを調べることができます)。IIS 7 では、上記の XML コードで示すように application/x-javascript が既定の MIME タイプです。どのようなアプリケーションについても、必要に応じ、web.config を使用してこの既定の MIME タイプを変更できます。次の例では、web.config で .js ファイルを application/x-javascript という MIME タイプから application/javascript にマッピングしています。 ファイルをその使用頻度に基づいて圧縮するように IIS 7 を構成することもできます。たとえば、あるページが特定の期間中に 2 回以上要求されない場合は、そのファイルを圧縮しないように指定できます。次のように serverRuntime 要素の frequentHitThreshold の値を 1 に設定した場合は、ファイルの要求が 1 回でも発生すると、その場で圧縮を強制実行できます。 IIS 7 を使用すると、JavaScript ファイルを圧縮できるだけでなく、静的な HTML ファイル、イメージ ファイル、CSS ファイル、および JavaScript ファイルについて、遠い将来を期限とする Expires ヘッダーを設定することもできます。遠い将来を期限とする Expires ヘッダーを設定すると、ファイルが無効にならない限り、ファイルの変更状況を確認するネットワーク呼び出しがブラウザーからサーバーに発行されなくなります。これにより、そのファイルをブラウザーのキャッシュから直接取得できるようになります。このタイプのヘッダーは、次の XML 構文を使用して web.config 内で設定できます。 この httpExpires 属性は正常に機能しますが、具体的な日付と時刻を入力する必要があり、これらはその日付が経過した後に変更する必要があります。IIS 7 は、キャッシュ制御値である最長有効期間 (秒単位) を指定できる "max-age" もサポートしています。次の構成セクションでは、コンテンツを 100 日間キャッシュに格納することをクライアントに指定しています。 5. まとめMicrosoft は、各種のブラウザーに対応した高機能で高性能な Web アプリケーションを構築できるように、JavaScript/Ajax アプリケーション環境を強化することに努めてきました。Microsoft Ajax CDN などのサービスや ASP.NET Ajax Library の Script Loader を利用することで、効率的なスクリプト読み込みを実現し、最新のブラウザー機能を活用できます。ASP.NET Ajax Library は CDN で jQuery ライブラリをサポートしているので、jQuery ライブラリを ASP.NET Ajax Library スクリプトと直接組み合わせて使用し、両方の利点を活用できます。 JavaScript アプリケーションのパフォーマンスは、各種のツールを使用して最適化できます。これらのツールとしては、JavaScript 関数の呼び出し方法を解析および最適化する Doloto、スクリプトを小型化する ASP.NET Ajax Minifier、JavaScript コードがページ内で実行される様子の詳しい解析やスクリプトのデバッグなどの機能を提供する IE 8 開発者ツールなどがあります。IIS 7 を使用すると、JavaScript ファイルを圧縮することで Ajax アプリケーションのパフォーマンス向上を図ることもできます。IIS 7 で可能な構成の変更では、圧縮するファイルの指定を制御できるほか、遠い将来を期限とする Expires ヘッダーを設定し、Ajax アプリケーション ファイルについてブラウザーからサーバーに発行する呼び出しの回数を最小限に抑えることもできます。 最新バージョンの ASP.NET Ajax Library をダウンロードするには、http://ajax.codeplex.com (英語) にアクセスしてください。 ASP.NET Ajax Library の詳細なドキュメントについては、http://www.asp.net/ajaxlibrary (英語) にアクセスしてください。 | ダウンロード
概要今日の Web アプリケーションの多くは JavaScript と Ajax をサポートすることで、サーバーとのデータ送受信回数を最小限に抑えて、エンド ユーザーがデスクトップ アプリケーションのような感覚で利用できるようにしています。しかしながら、開発上のいくつかの重要な原則を考慮して適用しないとパフォーマンス上の問題が発生する可能性があります。 このホワイト ペーパーでは、ASP.NET Ajax Library に焦点を当て、Ajax アプリケーションのパフォーマンス向上に役立つ各種の開発ルール、開発技法、および開発ツールを紹介します。 なお、このドキュメントは James Senior (Microsoft Corp. Web Platform Evangelist) と Dan Wahlin (Wahlin Consulting) 共著の「Building High Performance Web Applications」を日本語翻訳したものです。また、内容は ASP.NET Ajax Library 0911 Beta をベースに記述されており、正式版のリリースとともに変更されることがあります。 |