今回紹介するクラス
- Module
- ModuleBase
- ModuleLoader
- ModuleManager
今回はサンプル・サイトでメニュー毎のコンテンツのロードで使用していたSWFLoaderのアドバンス版とも言える「モジュール」の仕組みについて解説します。モジュールは Flex SDK 2.0.1 から導入された非常に優れた仕組みです。従来からあるSWFLoader(*1)と似ていますが,応用性は遥かに上です。
モジュールの最大の利点はFlexアプリケーションを分割するうえでクラスの重複をある程度自動的に除外し,ローディングに発生するオーバーヘッドを軽減できることです。ただ,欠点があります。それは若干ややこしく,少し面倒なところです。
まずは概要図を見てください(図1)。
図1●モジュールの仕組みの概要図 [画像のクリックで拡大表示] |
これだけを見ると「SWFLoaderと何が違うの?」と思われるかもしれません。確かに概要図だけを見ると非常に SWFLoader と似ています。ただ,SWFLoader で使用するSWFは通常のアプリケーションを作成するのと同じ手順ですが,モジュールは違います。用途に合わせて二つの方法があります。
- ビジュアル・モジュール
mx.module.Moduleを継承させることで作成できます(*2)。mx.core.LayoutContainerを継承しているためにモジュール自体がビジュアル性を備えています。 - 非ビジュアル・モジュール
mx.module.ModuleBaseを継承させることで作成できます(*3)。「非ビジュアル」と書きましたが,あくまでモジュールの“表面”が非ビジュアルなだけです。内部にビジュアル・コンポーネントを含ませることも可能です。
これらはSWFLoader と同じように必要な時に外部SWFをロードしますが,決定的な違いはファイル・サイズにあります。
ファイル・サイズ
モジュールはベースとなるFlexアプリケーションとの差分情報だけを含むようにすることができます。言葉だけではわかりにくいと思いますのでこちらの図をご覧ください(図2)。
図2●モジュールのコンパイル [画像のクリックで拡大表示] |
モジュールをコンパイルするには手順が必要です。
まずメインとなるアプリケーションをコンパイルするのですが(図2の手順1),report.xmlを生成するために,コンパイルオプション「-link-report」を指定する必要があります(*4)。指定方法は図3のようになります。
図3●「-link-report」の指定方法 [画像のクリックで拡大表示] |
FlexBuilder 2 ではこのように,「プロジェクトのプロパティ」→「Flex コンパイラ」→「追加コンパイラ引数」に出力するXMLのファイル名をフルパスで指定する必要があります。このreport.xmlの中にはコンパイルしたSWF内で使用されているクラスが列挙されています。
次にモジュールをコンパイルするのですが(図2の手順2),手順1で出力されたreport.xmlをコンパイルオプションで指定する必要があります。残念ながらFlexBuilder2ではこれができませんので,著者は下記のようなバッチをよく利用しました(*5)。
|
こうすることでreport.xmlに記述されているクラスはモジュールのSWFから除外され,その分だけファイル・サイズが小さくなります。実はモジュールは「-load-externs」を指定しなくてもコンパイルすることができます。しかし,その場合はどのクラスが重複しているのかわからないため,依存するクラスがすべて含まれてしまいます。
例えば図4のようにmx:Applicationだけのアプリケーションがあるとします。
図4●mx:Applicationだけのコード [画像のクリックで拡大表示] |
これをコンパイルするとリリースバージョンのSWFで124キロバイトもあります(*6)。そして,これに「-link-report」を指定した場合に,出力されるXML(こちらからダウンロードできます)に含まれるクラスの数は,Flex系が191個,Flash系が74個にもなります。仮にSWFLoaderで「Flexプロジェクト」で作成したSWFを読み込むとすると,これだけのクラスが重複することになります(本記事末のコラム「Flex 3ではFlexFrameworkがFlashPlayerにキャッシュされる」も参照)。
図2の手順3では実行時にモジュールSWFを指定したタイミングでロードするのですが,そのイメージは“マージする”感じです。エンタープライズ系の巨大なアプリケーションになればファイル・サイズも大きくなるので,初期ローディング時間が長くなります。そこでサブ機能や使用頻度が少ないライブラリなどをモジュール化することでファイル・サイズを分散し,初期ローディング時間を抑えることができます。
SWFLoader でロードできるSWFは独立して実行できますが,重複するクラスが含まれる場合にはロードにオーバーヘッドが発生してしまいます。