カスタム Dojo 成果物のための、最適化された Dojo ビルドを作成する

カスタム・ウィジェットのためのカスタム Dojo ビルドを、Dojo/Dijit/Dojox パッケージのモジュールをビルド出力に含めずに作成しましょう。カスタム Dojo ビルドを作成すると、すべてのモジュールを組み合わせて 1 つのファイルにすることができるため、ダウンロードする必要のあるモジュールの数を減らすことができます。これにより、個々のモジュール・ファイルをダウンロードするためのネットワーク呼び出しの回数を減らすことができます。こうした手法は、パッケージを小さくする必要のある実際のプロジェクトで開発されたものです。この記事は、最適化された Dojo ビルドを Dojo のビルド・ツールを使って作成する際に役立つ内容になっています。

Manjunath Ganga, Software Engineer, IBM  

Manjunath Ganga はこの 2 年間、WebSphere Commerce IBM India チームのソフトウェア開発者として働いてきました。現在は Websphere Commerce のソーシャル・コマース・ソリューションに従事しています。彼の専門は、Java、J2EE、Ajax、Dojo、Wesbphere Smash です。



2009年 11月 10日

はじめに

Dojo のソース・ディストリビューションには何千ものファイルが含まれており、それらはパッケージ (ディレクトリー) に分けられて構成されています。また、独自のカスタム・モジュールを作成することもできますが、そうしたモジュールは Dojo のソース・ツリーとは別のパッケージにしておくのが望ましいです。Dojo.require() 文があるごとに、その要求されたモジュールのために、サーバーに対して同期 HTTP 呼び出しが行われます。ブラウザーはそれぞれの同期呼び出しが完了するのを待ってから他の動作を継続するため、こうした呼び出しはパフォーマンスに大きく影響します。特に、モジュールが依存関係を数多く持つ大規模なアプリケーションでは影響が大きくなります。また、モジュールをオリジナルのファイル形式のままダウンロードする場合には、多くの時間と帯域幅を必要とします。

以下の内容を実行してカスタム Dojo ビルドを作成すると、パフォーマンスを改善することができます。

  • 個々のモジュールをグループ化してレイヤーにします。レイヤーは 1 つの大きな .js ファイルであり、そのレイヤーを構成する個々の .js モジュールよりも高速にロードされます。
  • JavaScript ファイル以外の外部ファイルを内部化します。例えば Dijit テンプレートの場合であれば、HTML テンプレート・ファイル全体を抽出して 1 つのストリングとして扱うようにします。
  • Shrinksafe というツールでレイヤーを圧縮します。レイヤー・ファイルは大きいため、この圧縮によって大幅にファイル・サイズを小さくすることで、ロード時間が短縮されます。またファイル・サイズが小さくなるため、ブラウザー・エンジンがファイルを解析する時間も短縮することができます。

ここで、カスタム Dojo 成果物 (例えばカスタム Dojo ウィジェット) を作成し、あるサイトでホストすることで、潜在クライアントが彼らのサイトにこれらの成果物をデプロイできるようにした、という状況を考えてみましょう。さらに、作成されたカスタム Dojo のためのレイヤー・ファイルも作成したとします。すると、クライアントはそのレイヤー・ファイルを 1 度リクエストすればよく、必要なそれぞれのモジュールごとにリクエストを実行する必要がなくなります。

また、カスタム Dojo 成果物をデプロイするクライアント・サイトが Dojo に対応していれば、Dojo/Dijit/Dojox パッケージのモジュールを何も含めないようにすることで、カスタム・レイヤー・ファイルのサイズをさらに小さくすることができます。なぜなら、それらのモジュールは既にクライアント・サイトに存在しているはずだからからです。この記事では、このように Dojo ツリーのモジュールを含まないカスタム・レイヤー・ファイルを作成する方法について説明します。

図 1. デプロイメントのシナリオ
2 つのボックスが 2 本の矢印で結ばれており、それぞれの矢印は、クライアント・サイトから送信されるレイヤー・ファイルと、サーバー・サイトからクライアント・サイトに返されるカスタム Dojo レイヤー・ファイルを示しています。

前提条件

この記事では、Dojo のビルド・ツールを使って Dojo のレイヤー・ファイルを作成する方法を説明します。Dojo のビルド・ツールを使用するための要件は以下のとおりです。

  • Java™ 1.4.2 またはそれ以降 (Java 1.5 を推奨)
  • Dojo のソース・ビルド (ダウンロードについては「参考文献」を参照)。

セットアップ

セットアップは以下の手順で行います。

  1. ディレクトリー (例えば build) を作成します。このディレクトリーは、すべての作業のルート・ディレクトリーとして機能します。
  2. build の下に新しいディレクトリー (例えば Dojo1.3) を作成し、そのディレクトリーに Dojo のソース・ビルドを解凍します。この記事のここから先では、build/Dojo1.3 を DojoRootDir と呼ぶことにします。
  3. DojoRootDir の下に custom というディレクトリーを作成します。これから作成するカスタム Dojo 成果物はすべて、このディレクトリーに配置されます。

これで、リスト 1 に示すようなアプリケーションのディレクトリー構造が DojoRootDir の下に作成されたはずです。

リスト 1. アプリケーションのディレクトリー構造
build/ 
                 dojo1.3/ 
                                  custom/ 
                                  dojo/ 
                                  dijit/ 
                                  dojox/ 
                                  util/

Dojo のプロファイル

Dojo のプロファイルは Dojo のビルド・ツールの必須入力パラメーターであり、ビルド・システムがカスタム・レイヤーを作成する方法を指定するのもこのパラメーターです。このプロファイルは JavaScript ファイルであり、Apache Ant で使用される build.xml ファイルと同じような機能を持ちます。そして、Dojo ビルド・ツールがカスタム Dojo レイヤーを作成する上で必要な情報は、すべてこの Dojo プロファイルにカプセル化されています。この記事では、目標とするカスタム Dojo レイヤーを作成する上で必要な Dojo のプロファイルを作成する方法について説明します。サンプル・プロファイルのスクリプトは、記事に添付してあります (「ダウンロード'」を参照)。

リスト 2 は Dojo のビルド・プロファイルの構造を示しています。

リスト 2. Dojo のビルド・プロファイルの構造
dependencies = {
          
            layers : [ ],

            prefixes : [ ]
 
   };

layers セクションは、これから作成するレイヤー・ファイルの配列です。(1 回のビルドの実行で複数のレイヤー・ファイルを作成することができます。)

prefixes セクションは個々の prefix オブジェクトの配列です。各 prefix オブジェクトは、DojoRootDir/Dojo から相対的に見て、ある特定の最上位レベルのモジュールのソースがどこにあるかを記述します。


カスタム Dojo ビルドを実行する

Dojo のビルド・スクリプトは DojoRootDir/util/buildscripts ディレクトリーにあります。このディレクトリーから、ビルド・ツールを以下のように実行します。

  ./build.sh profileFile=<path to the profile file> 
            action=<actions>

この場合のオプションの概要を示したものが表 1 です。

表 1. Dojo のビルド・オプション
ビルド・オプションの名前説明
profileFileプロファイル・ファイルへのファイル・パス。このパスは、プロファイルが DojoRootDir/util/buildscripts/profiles ディレクトリーの外にある場合に使われます。
action実行対象のビルド・アクション。例えば action=clean, release のようなカンマ区切りリスト。指定可能なビルド・アクションには、clean, release などがあります。デフォルトは help です。

build.sh を何もオプションを付けずに実行すると、サポートされているすべてのオプションのリストが表示されます。(注記: Windows® の場合は build.bat を使います。)


カスタム Dojo プロファイルを作成する

ここでは、リスト 1 の custom ディレクトリーの下にあるリソースを含む Dojo レイヤー・ファイルを作成する必要がありますが、このレイヤー・ファイルは Dojo/Dijit/Dojox パッケージのモジュールを含めるべきではありません (これらのモジュールはクライアント・サイトにあるため)。

ある 1 つのレイヤーからモジュールを削除するためには、これらのモジュールを discard レイヤーに含め、この discard レイヤーをターゲット・レイヤーの layerDependencies 属性で指定する必要があります。次の例を見ると、この意味がわかるはずです。

例えば、layerA というレイヤー・ファイルを作成しているとします。この layerA には (モジュール modB と modC に対して依存関係を持つ) modA を含める必要がありますが、モジュール modB と modC を含めるべきではありません (これらのモジュールは別のレイヤーに含まれている可能性があるため)。そのためには、モジュール modB と modC を discardLayer レイヤーに含め、この discardLayer レイヤーを layerA に対するレイヤー依存関係として指定します。リスト 3 は、そうしたプロファイルを作成する方法を示しています。

リスト 3. discard レイヤーの作成方法を説明する Dojo プロファイルの例
dependencies: {

     layers: [
          {
          	"name": "discardLayer",
          	"discard" : "true",
          	"dependencies": 
               [
               	"custom.modB",
               	"custom.modC"
               ]
          },

          {
          	"name": "layerA",
          	"layerDependencies" : 
               [
               	"discardLayer"                             ],
          	"dependencies" :
               [
               	"custom.modA"
               ]
          }
            ],

     prefixes: 
     	[
          ["custom": "../custom"]
     	]

}

注 1: layerDependencies 属性は、あるレイヤーの前提条件である他のレイヤーを指定します。前提となるレイヤーに含まれるリソースが、現在作成中のレイヤーに重複して含まれることはありません。つまり、Dojo ビルダーがソース・ファイルの中で Dojo.require 文を発見し、ただしそのリソースが依存関係レイヤー群の 1 つに既に配置されている場合には、そのリソースは現在のレイヤーには含まれません。

注 2: プロファイルの中でのレイヤー・ファイルの順序が重要です。レイヤー・ファイルはプロファイルの中に現れる順に作成されます。これは重要です。なぜなら、作成対象のレイヤー・ファイル (layerA) よりも前に discard レイヤー (discardLayer) を定義する必要があるからです。こうすることで、discard レイヤーに含まれるモジュールは作成対象のレイヤーに含まれなくなります。discard 属性が true に設定されたレイヤーは、ビルドが完了した後は保存されません。つまり discardLayer は、ビルドが完了した後は保存されず、モジュール modB と modC が layerA に含まれないようにする役割を果たすためだけにあるのです。

この方法を使用してレイヤー・ファイルを作成するためには、以下のステップに従います。

  1. Dojo パッケージのモジュール群に対する discard レイヤーを作成します。
  2. Dijit パッケージのモジュール群に対する discard レイヤーを作成します。
  3. Dojox パッケージのモジュール群に対する discard レイヤーを作成します。
  4. 必要なモジュールを含むようにレイヤーを作成し、上記のレイヤー群をレイヤー依存関係として指定します。

プロファイルをリスト 4 のように作成し、myProf.profile.js として保存します。

リスト 4. カスタム・モジュールを含み、Dojo/Dijit/Dojox パッケージのモジュールを除外する Dojo プロファイル
dependencies = {
layers: 
[   
//This layer is used to discard modules             
//from the dojo package.      
                  
{ 		    
name: "dojo.js",
customBase: true,
discard: true,
			dependencies: 
[
                  	"dojo._base"
			]
			
		},
		
//This layer is used to discard modules             
//from the dijit package.      

{
			name: "../dijit/dijit.js",
			dependencies: 
[
				"dijit.dijit",  
                    "dijit.dijit-all"                                         

			],
			discard: true
		},
 //This layer is used to discard modules             
//from the dojox package

{
			name: "../dojox/dojox.js",
			dependencies: [
			//modules to be included from the dojox 
                                            //package, for example dojox.fx if  
                                            //this module is used in our code
                        ],
			discard: true
		},

	       

              //Custom layer mydojo.js which
              // includes our custom Dojo artifacts               
           {
              	//place the file under dojoRootDir 
              	name: "../../../mydojo.js",                                           
              	resourceName: "mydojo",
              	layerDependencies: 
[
                   	"dojo.js",                                           
                   	"../dijit/dijit.js",
                   	"../dojox/dojox.js"
               ],                                                                    
               dependencies: 
[
                               //modules to be included from the
                               //custom project. You can probably 
		  //list a single module here which in
		  //turn declares all the required
		  //modules as opposed to listing all the
		  //modules individually. Please take a 
		  //look at dojoRootDir/dojo/_base.js 
		  //file for an example.
                ]
             }
        ],

        prefixes: [
                         ["dijit", "../dijit"],
                         ["dojox", "../dojox"],
                         ["custom", "../custom"]
        ]
	
}

: リスト 4 で、discard レイヤーに対して指定されたモジュール群 (各レイヤーの dependencies 属性に対して与えられた値) によって、各対象パッケージからすべてのモジュールが削除されるとは限りません。例えばリスト 4 の Dojo.js レイヤーによって、Dojo のベース・モジュールはまったく含まれなくなりますが、Dojo.io パッケージのモジュールは含まれてしまいます。これは、Dojo.io パッケージのモジュールがカスタム・コードに必要なければ問題になりません。もし、Dojo.io パッケージのモジュールがカスタム・コードに必要な場合には、そのモジュールがレイヤー・ファイルに含まれることになり、レイヤー・ファイルのサイズが大きくなります。そのため、レイヤー・ファイルから除外する必要があるモジュールがすべて確実に、いずれかの discard レイヤーに含まれているようにする必要があります。


ビルドを実行し、レイヤー・ファイルを作成する

プロファイルを作成できたら、ビルド・ツールを実行してレイヤー・ファイルを作成することができます (リスト 5)。

リスト 5. ビルド・ツールを実行してカスタム・レイヤーを作成する
./build.sh profileFile=<dojoRootDir>/myProf
         action=clean, release releaseName=myRelease.

リスト 5 のビルドを実行すると、myDojo.js というレイヤー・ファイルが <DojoRootDir> ディレクトリーの下に作成されます。すると、このレイヤー・ファイルを Web サーバーにコピーすることができ、クライアントはこのファイルをダウンロードすることができます。


クライアント・サイドにレイヤー・ファイルを含める

クライアントがカスタム Dojo 成果物を使用する必要がある場合には、作成されたレイヤー・ファイルを参照することでそれが可能になります (リスト 6)。

リスト 6. レイヤー・ファイルのダウンロード方法を示すコード・スニペット
<!--Load Dojo from the client site -->
<script type="text/javascript" 
src="<clientDojoRootDir>/dojo/dojo.js"></script>

<!—Now load our layer file -->
<script type="text/javascript" 
src="http://www.mysite.com/mydojo.js"></script>

これで完成です!クライアントは、1 つのリクエストのみでカスタム Dojo 成果物を使用できるようになりました。


潜在的な問題

このクライアント・サイドへの統合がうまくいくかどうかはクライアントにかかっています。つまり、クライアントは Dojo/Dijit/Dojox パッケージのモジュールを提供しなければなりませんが、クライアント自身が既にカスタム Dojo ビルドを作成している可能性は十分にあり、その場合 Dojo/Dijit/Dojox パッケージの一部のモジュールをクライアントのレイヤー・ファイルに含めていない可能性があるということです。これが問題となるのは、クライアントのレイヤー・ファイルから破棄されたモジュールが、カスタム Dojo コードにとって必要な場合です。

この問題は次のようなシナリオを考えると理解しやすくなります。

例えば、カスタム Dojo コードが dijit.ComboBox モジュールに対する依存関係を持っているとします。このモジュールは Dijit パッケージの一部であるため、レイヤー・ファイルには含まれません。もし、dijit.ComboBox を含まないカスタム・レイヤーをクライアントが使用している場合、Dojo.require("dijit.ComboBox") 文を実行すると、dijit.ComboBox モジュールが明示的にダウンロードされると読者の皆さんは思うかもしれません。しかしこの場合には、このビルドを実行すると、すべての Dojo.require() 文はレイヤーから削除されてしまうため、dijit.ComboBox モジュールはロードされません。その結果、このモジュールを参照するコードが実行されるとエラーが発生します。

この問題に対する解決策としては、このようなモジュールを見つけ、それらのモジュールに対する Dojo.require() 文をレイヤー・ファイルの先頭に追加します。こうすることで、これらのモジュールは他から参照される前にすべてロードされるようになります。


まとめ

この記事では、カスタム Dojo 成果物に対するカスタム Dojo レイヤーを作成する方法について説明しました。また、このレイヤー・ファイルをさらに最適化し、Dojo/Dijit/Dojox パッケージのモジュールを含まないようにする方法についても説明しました。このようにする理由は、それらのモジュールはレイヤー・ファイルがデプロイされるサイトに既に存在しているはずだからです。またこの記事では、この統合に伴う潜在的な問題と、その問題を克服する方法についても説明しました。


ダウンロード

内容ファイル名サイズ
Sample downloadSampleCode.zip2KB

参考文献

学ぶために

製品や技術を入手するために

  • 最新バージョンの Dojo をプロジェクトの Web サイトからダウンロードしてください。(ソース・ビルドには「-src」という接尾辞が付いています。)

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=454263
ArticleTitle=カスタム Dojo 成果物のための、最適化された Dojo ビルドを作成する
publish-date=11102009