MXML 言語には、インタラクティブなアプリケーションの作成に使用できる高性能なコントロールとクラスのセットが用意されています。これらの高性能なコントロールとクラスを使用すると、パフォーマンスが低下することがあります。ただし、Flex アプリケーションの実行時のパフォーマンスを改善するために Flex 開発者が使用できるテクニックがいくつかあります。
これらのテクニックの効果を測定するには、Flex プロファイラを使用します。詳細については、『Adobe Flex Builder 3 ユーザーガイド』のFlex アプリケーションのプロファイリングを参照してください。
オブジェクトの作成は、アプリケーション内のすべてのオブジェクトをインスタンス化するタスクです。これらのオブジェクトには、コントロールやコンポーネント、およびデータやその他の動的な情報が含まれるオブジェクトなどがあります。オブジェクト作成プロセスを最適化すると、パフォーマンスが大幅に改善されることがあります。オブジェクトの破棄は、すべてのオブジェクトが削除された後に、メモリを再割り当てする操作です。この作業は、定期的にガベージコレクタによって行われます。オブジェクトへの参照を削除することで、Flash Player と AIR がオブジェクトを破棄する頻度を少なくすることができます。
アプリケーションの初期化中のタスクは、どれも同じくらいの時間がかかります。パフォーマンスの向上を図る最善の方法は、生成されるオブジェクトの数を減らすことです。これを行うには、オブジェクトのインスタンス化を遅らせたり、体感的なパフォーマンスが向上するように生成順序を変更したりします。
初期ビューでコンテナを作成する順序を設定すると、Flex アプリケーションの起動時間が短く感じられるようになります。Flex のデフォルトの動作では、初期ビューでコンテナとその子オブジェクトがすべて生成されてから、一斉に表示されます。すべてのコンテナとその子オブジェクトが生成されるまでは、ユーザーはアプリケーションを操作したり、意味のあるデータを表示したりできません。
場合によっては、1 つのコンテナのコンポーネントを表示してから次のコンテナのコンポーネントの生成に移るようにすると、起動時のユーザー体験を向上させることができます。このプロセスを、順序付き生成と呼びます。
順序付き生成を使用するには、次の例のように、コンテナの creationPolicy プロパティを queued に設定します。
<?xml version="1.0"?>
<!-- optimize/QueuedPanels.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel id="panel1" creationPolicy="queued" width="100%" height="33%">
<mx:Button id="button1a"/>
<mx:Button id="button1b"/>
</mx:Panel>
<mx:Panel id="panel2" creationPolicy="queued" width="100%" height="33%">
<mx:Button id="button2a"/>
<mx:Button id="button2b"/>
</mx:Panel>
<mx:Panel id="panel3" creationPolicy="queued" width="100%" height="33%">
<mx:Button id="button3a"/>
<mx:Button id="button3b"/>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
このようにすると、コンテナの子がキューに追加されます。Flash Player では、キューの最初のコンテナに含まれるすべての子をインスタンス化して表示してから、そのキューの次のコンテナに含まれる子がインスタンス化されます。
順序付き生成の詳細については、順序付き生成の使用を参照してください。
アプリケーションの起動時間を短縮するには、アプリケーションが最初にロードされるときに作成されるオブジェクトの数を最小限に抑えます。ユーザーインターフェイスのコンポーネントを起動時に表示しない場合は、そのコンポーネントを必要な場合にのみ作成します。これを、遅延生成と呼びます。Accordion など複数のビューを持つコンテナでは、この機能がビルトインでサポートされています。ActionScript を使用すると、複数ビューコンテナの作成順序をカスタマイズしたり、他のコンテナやコントロールの作成を延期させたりできます。
遅延生成を使用するには、コンポーネントの creationPolicy プロパティの値を all、auto、または none に設定します。none に設定すると、Flex はコントロールの子を直ちにインスタンス化しないで、明示的な指示があるまで待機します。次の例では、アプリケーションが最初にロードされたときには VBox コンテナの子がインスタンス化されず、ユーザーがボタンをクリックした後にインスタンス化されます。
<?xml version="1.0"?>
<!-- optimize/CreationPolicyNone.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
private function createButtons(e:Event):void {
myVBox.createComponentsFromDescriptors();
}
]]></mx:Script>
<mx:Panel title="VBox with Repeater">
<mx:VBox id="myVBox" height="100" width="125" creationPolicy="none">
<mx:Button id="b1" label="Hurley"/>
<mx:Button id="b2" label="Jack"/>
<mx:Button id="b3" label="Sawyer"/>
</mx:VBox>
</mx:Panel>
<mx:Button id="myButton" click="createButtons(event)" label="Create Buttons"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
実行時に子をインスタンス化する場合は、コンテナに対して createComponentFromDescriptor() や createComponentsFromDescriptor() などのメソッドを呼び出します。遅延インスタンス化の使用の詳細については、遅延生成の使用を参照してください。
Flash Player には、使用されなくなったオブジェクトを破棄することによってメモリを解放する、組み込みのガベージコレクションが用意されています。使用していないオブジェクトがガベージコレクタによって必ず破棄されるように、子に対する親の参照など、使用していないオブジェクトに対するすべての参照を削除してください。
ガベージコレクションの詳細については、『Adobe Flex Builder 3 ユーザーガイド』のガベージコレクションについてを参照してください。
不要になった子コントロールに対する参照をコンテナから削除する場合は、removeChild() または removeChildAt() メソッドを呼び出します。次の例では、myVBox コントロールからボタンインスタンスへの参照が削除されます。
<?xml version="1.0"?>
<!-- optimize/DestroyObjects.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
private function destroyButtons(e:Event):void {
myVBox.removeChild(b1);
myVBox.removeChild(b2);
myVBox.removeChild(b3);
}
]]></mx:Script>
<mx:Panel title="VBox with Repeater">
<mx:VBox id="myVBox" height="100" width="125">
<mx:Button id="b1" label="Hurley"/>
<mx:Button id="b2" label="Jack"/>
<mx:Button id="b3" label="Sawyer"/>
</mx:VBox>
</mx:Panel>
<mx:Button id="myButton2" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
使用していない変数に対する参照をクリアする場合は、次のように、ActionScript でこれを null に設定します。
myDataProvider = null
破棄されたオブジェクトがガベージコレクションの対象となるようにするには、次の例のように、removeEventListener() メソッドを使用して、これらのオブジェクトのイベントリスナーも削除する必要があります。
<?xml version="1.0"?>
<!-- optimize/RemoveListeners.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)">
<mx:Script><![CDATA[
private function initApp(e:Event):void {
b1.addEventListener("click",myClickHandler);
b2.addEventListener("click",myClickHandler);
b3.addEventListener("click",myClickHandler);
}
private function destroyButtons(e:Event):void {
b1.removeEventListener("click",myClickHandler);
b2.removeEventListener("click",myClickHandler);
b3.removeEventListener("click",myClickHandler);
myVBox.removeChild(b1);
myVBox.removeChild(b2);
myVBox.removeChild(b3);
}
private function myClickHandler(e:Event):void {
// Do something here.
}
]]></mx:Script>
<mx:Panel title="VBox with Repeater">
<mx:VBox id="myVBox" height="100" width="125">
<mx:Button id="b1" label="Hurley"/>
<mx:Button id="b2" label="Jack"/>
<mx:Button id="b3" label="Sawyer"/>
</mx:VBox>
</mx:Panel>
<mx:Button id="myButton" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
インラインで追加したイベントハンドラについて removeEventListener() メソッドを呼び出すことはできません。次の例では、b1 の clickイベントハンドラについては removeEventListener() を呼び出すことができませんが、b2 と b3 のイベントハンドラについてはこれを呼び出すことができます。
<?xml version="1.0"?>
<!-- optimize/RemoveSomeListeners.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)">
<mx:Script><![CDATA[
private function initApp(e:Event):void {
b2.addEventListener("click",myClickHandler);
b3.addEventListener("click",myClickHandler);
}
private function destroyButtons(e:Event):void {
b2.removeEventListener("click",myClickHandler);
b3.removeEventListener("click",myClickHandler);
myVBox.removeChild(b1);
myVBox.removeChild(b2);
myVBox.removeChild(b3);
}
private function myClickHandler(e:Event):void {
// Do something here.
}
]]></mx:Script>
<mx:Panel title="VBox with Repeater">
<mx:VBox id="myVBox" height="100" width="125">
<mx:Button id="b1" label="Hurley" click="myClickHandler(event)"/>
<mx:Button id="b2" label="Jack"/>
<mx:Button id="b3" label="Sawyer"/>
</mx:VBox>
</mx:Panel>
<mx:Button id="myButton" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
addEventListener() メソッドで weakRef パラメータを使用すると、リスナーのメモリリソースを制御できます。強参照の場合(weakRef が false の場合)は、リスナーのガベージコレクションが回避されます。弱参照(weakRef が true)では回避されません。デフォルトは false です。
removeEventListener() メソッドの詳細については、『Adobe Flex 3 開発ガイド』のイベントの使用を参照してください。
スタイルは、Flex アプリケーションの外観と操作性を定義する場合に使用します。スタイルを使用して、1 つのコンポーネントの外観を変更したり、グローバルに同じ外観を適用することができます。スタイルを適用する方法によっては、負荷が高くなることがあるので注意してください。スタイルの適用方法を変更すると、アプリケーションのパフォーマンスが改善することもあります。
スタイルの使用の詳細については、『Adobe Flex 3 開発ガイド』のスタイルとテーマの使用を参照してください。
StyleManager を使用することで、実行時にスタイルシートをロードできます。これらのスタイルシートは、Flex アプリケーションの実行中に動的にロードされる SWF ファイルの形式を取ります。
実行時にスタイルシートをロードすると、イメージ(グラフィカルスキン用)、フォント、タイプセレクタとクラスセレクタ、およびプログラムスキンを、コンパイル時に埋め込まずに Flex アプリケーションにロードできます。この方法では、スキンとフォントをメインアプリケーションとは分離した別個の SWF ファイルに分割することができます。その結果、アプリケーションの SWF ファイルのサイズは縮小し、初期ダウンロードの時間は短縮されます。ただし、実行時スタイルシートを初めて使用するときは、必要な CSS ベースの SWF ファイルを Flex にダウンロードする必要があるため、スタイルおよびスキンの適用に時間がかかります。
詳細については、Adobe Flex 3 開発ガイドを参照してください。
実行時のカスケーディングスタイルは非常に有用ですが、慎重に正しいコンテキストで使用します。setStyle() メソッドを呼び出すと、新たにスタイルを設定するオブジェクトのすべての子に通知が行われるので、負荷が高くなることがあります。通知を必要とする子のツリーは、非常に大きくなる場合があります。
パフォーマンスに影響する失敗として一般的なものは、setStyle() メソッドの過剰な使用や不必要な使用です。一般に、setStyle() メソッドを使用するのは、既存のオブジェクトのスタイルを変更する場合のみです。オブジェクトのスタイルを初めて設定する際には使用しないでください。代わりに、外部 CSS スタイルシートを使用し MXML タグの明示的なスタイルプロパティとして <mx:Style> ブロックでスタイルを設定するか、またはグローバルスタイルとしてスタイルを設定します。
アプリケーションによっては、アプリケーションまたはオブジェクトのインスタンス化の際に setStyle() メソッドを呼び出す必要があります。その場合、初期化の早い段階で setStyle() メソッドを呼び出します。つまり initialize イベントや creationComplete イベントではなく、コンポーネントまたはアプリケーションの preinitialize イベントからスタイルを設定します。初期化の際にできるだけ早くスタイルを設定することで、不要なスタイル通知や参照を避けます。
プログラムによってコンポーネントを生成し、そのコンポーネントにスタイルを設定する場合は、次の例に示すように、setStyle() メソッドを呼び出してから、addChild() メソッドを呼び出して、これを表示リストに関連付けます。
<?xml version="1.0"?>
<!-- optimize/CreateStyledButton.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)">
<mx:Script><![CDATA[
import mx.controls.Button;
public function initApp(e:Event):void {
var b:Button = new Button();
b.label="Click Me";
b.setStyle("color", 0x00CCFF);
panel1.addChild(b);
}
]]></mx:Script>
<mx:Panel id="panel1"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
実行時のグローバルスタイルの変更(クラスまたはタイプセレクタに関連付けられた CSS ルールセットの変更)は、負荷がかかる操作です。グローバルスタイルを変更するたびに、Flash Player では次の操作が実行されます。
次の例では、Button コントロールのカラーのスタイルプロパティをグローバル変更します。
<?xml version="1.0"?>
<!-- optimize/ApplyGlobalStyles.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)">
<mx:Script><![CDATA[
public function initApp(e:Event):void {
StyleManager.getStyleDeclaration("Button").setStyle("color", 0x00CCFF);
}
]]></mx:Script>
<mx:Panel id="panel1">
<mx:Button id="b1" label="Click Me"/>
<mx:Button id="b2" label="Click Me"/>
<mx:Button id="b3" label="Click Me"/>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
可能であれば、作成時に CSS を使用してグローバルスタイルを設定します。実行時に設定する場合は、setStyle() メソッド呼び出しの削減で説明した方法を使用してスタイルを設定します。
setStyleDeclaration() および loadStyleDeclarations() メソッドの呼び出し
setStyleDeclaration() メソッドは多くの計算処理を伴います。update パラメータを false に設定すると、新しいスタイルが Flash Player で直ちに適用またはクリアされないようにできます。
次の例では、さまざまなターゲットに新しいクラスセレクタを設定しますが、最後のスタイル宣言の適用まで更新をトリガしません。
<?xml version="1.0"?>
<!-- styles/SetStyleDeclarationExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
<mx:Script><![CDATA[
import mx.styles.StyleManager;
private var myButtonStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myButtonStyle');
private var myLabelStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myLabelStyle');
private var myTextAreaStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myTextAreaStyle');
private function initApp():void {
myButtonStyle.setStyle('color', 'blue');
myLabelStyle.setStyle('color', 'blue');
myTextAreaStyle.setStyle('color', 'blue');
}
private function applyStyles():void {
StyleManager.setStyleDeclaration("Button", myButtonStyle, false);
StyleManager.setStyleDeclaration("Label", myLabelStyle, false);
StyleManager.setStyleDeclaration("TextArea", myTextAreaStyle, true);
}
]]></mx:Script>
<mx:Button id="myButton" label="Click Me" click="applyStyles()"/>
<mx:Label id="myLabel" text="This is a label"/>
<mx:TextArea id="myTextArea" text="This is a TextArea"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
update パラメータに false を渡すと、セレクタは保存されますが、スタイルは適用されません。update パラメータに true を渡した場合、Flash Player はアプリケーションに含まれる各ビジュアルコンポーネントのスタイルを再計算します。
loadStyleDeclarations() メソッドは同様に多くの計算処理を伴います。新しいスタイルシートをロードすると、このメソッドはデフォルトで表示リストの更新をトリガします。update パラメータを false に設定すると、新しいスタイルシートを Flash Player が直ちに適用またはクリアしないようにできます。loadStyleDeclarations() メソッドの呼び出しをチェーンにするときは、最後の呼び出しを除くすべての呼び出しで、更新パラメータを false に設定します。
コンテナは、子のレイアウト属性を制御できる階層構造を提供します。コンテナを使用すると、子のサイズと位置、複数の子コンテナ間のナビゲーションを制御できます。
Flex アプリケーションを開発する場合は、使用するコンテナ数を最小限に抑えるようにしてください。これは、ほとんどのコンテナではサイズと位置を相対的に調整するためです。特にアプリケーションを最初に起動するときなどは、多くのリソースを必要とする操作となることがあります。
よくある間違いに、子を 1 つだけ含むコンテナを作成することがあります。子を 1 つだけ含むコンテナが必要な場合もあります。例えば、コンテナのパディングを使用して子を配置する場合などです。しかし、通常はこのような実質的な機能のないコンテナがないか確認し、見つけた場合は削除します。MXML コンポーネントのルートはコンテナでなくてもかまわないという点にも留意してください。
コンテナを別のコンテナの内部にネストしたときに、親コンテナと子コンテナの両方のタイプが同じ場合も(HBoxes など)、コンテナの数が多くなりすぎている可能性があります。
レイアウトを何重にもネストすることはできるだけ避けることをお勧めします。単純なアプリケーションで、コンテナを 3 レベル以上ネストしている場合は、同じレイアウトを少ないレベルのネストで作成できる可能性があります。ネストを深くすると、パフォーマンスに問題が生じる場合があります。大規模なアプリケーションでは、深いネストが避けられないことがあります。
コンテナをネストすると、各コンテナインスタンスが子(一部はコンテナそのものなので、測定手順は再帰的となることがあります)について測定およびサイズ調整アルゴリズムを実行します。レイアウトアルゴリズムが処理され、相対レイアウト値が計算されると、Flash Player は、ビューを構成するオブジェクトの複雑なコレクションを描画します。オブジェクトの生成時に不要な作業を排除することにより、アプリケーションのパフォーマンスを改善できます。
Grid コンテナは複数のオブジェクトを整列させるのに便利です。ただし、Grid コンテナを使用すると、GridItem コントロールと GridRow コントロールを含むコンテナのレベルが新たに追加されます。多くの場合、VBox コンテナと HBox コンテナを使用しても同じ結果が得られます。これらのコンテナを使用した方がネストのレベルは少なくなります。
Canvas コンテナを使用すると、アプリケーションの起動時間が短縮される場合があります。このコンテナは、Form、HBox、VBox、Grid、Tile などのコンテナとは異なり、相対的にレイアウトするのではなく絶対配置を行います。
デフォルトでコンテナ内の子コントロールの配置を指定できるのは、Canvas コンテナだけです。他のすべてのコンテナはデフォルトで相対コンテナになります。つまり、コンテナ内の他のコンポーネントを基準にしてすべてをレイアウトします。Application コンテナと Panel コンテナは、絶対配置を行うように変更できます。
Canvas コンテナでは、起動時にコンテナの子の位置を自動設定するために他のコンテナで使用されるレイアウトロジックがなく、ピクセル単位で明示的な位置指定を行います。Canvas コンテナを使用する場合には、コンテナ内のすべての子の X 位置と Y 位置を設定しておく必要があります。x位置と y 位置を設定しなかった場合、Canvas コンテナの子は、デフォルトの x 座標と y 座標(0,0)に、相互に積み重なって配置されます。
ただし、Canvas コンテナは子を含む十分な大きさがあることを確認するためにそれ自体の大きさを測定する必要があるので、他のコンテナよりも常に効率がよいわけではありません。Canvas を使用するアプリケーションのオブジェクト階層は、通常は他のコンテナよりもずっと平らです。このため、Canvas コンテナを使用すると、ネストのレベルを減らすことができ、コンテナの総数を削減できるので、パフォーマンスが向上します。
Canvas コンテナは制約をサポートしています。つまり、コンテナのサイズが変更されると、そのコンテナ内の子もそれに従って移動します。
オブジェクトの幅と高さをコードに記述すると、Flex のレイアウトコンテナが実行時にオブジェクトのサイズを計算する必要がないので、時間が短縮されます。コンテナやコントロールの幅または高さを指定すると、相対レイアウトコンテナの処理負荷が小さくなり、その結果、コンテナとコントロールの生成時間が短縮されます。この方法はどのコンテナやコントロールにも使用できます。
エフェクトを使用すると、ユーザーまたはプログラムの操作に応じて、アニメーションやモーションをアプリケーションに追加できます。例えば、フォーカスが移ったときにダイアログボックスがわずかに飛び跳ねるような効果を出したり、ダイアログボックスがゆっくり表示状態に推移するフェードイン効果を実装したりすることもできます。
エフェクトは Flex アプリケーションが実行するタスクの中で最もプロセッサ負荷の高いものの 1 つに数えられます。この節で説明する方法を使用すると、エフェクトのパフォーマンスを改善できます。詳細については、『Adobe Flex 3 開発ガイド』のビヘイビアの使用を参照してください。
エフェクトの継続時間を延長する場合は duration プロパティを使用します。エフェクトの継続時間を長くすると、変化に富んだ個々のステージがより長い時間にわたって再生されるので、ステージ間の差が目立たなくなりスムーズに見えるようになります。
エフェクトの開始時にターゲットビューのパーツを非表示にし、エフェクトの再生が終了してからそれらのパーツを表示します。これは、エフェクトの前後に表示する内容を制御する effectStart および effectEnd イベントハンドラにロジックを追加して行います。
例えば、Panel コンテナに Resize エフェクトを適用すると、エフェクトが継続している間、このエフェクトのための測定とレイアウトのアルゴリズムが繰り返し実行されます。Panel コンテナに多数の子が存在する場合、Flex が十分な速度で画面を更新できず、アニメーションの描画がぎこちなくなる場合があります。1 つの Panel コンテナのサイズを調整すると、多くの場合、同じビュー内の他の Panel コンテナのサイズも調整されます。
この問題を解決するには、Resize エフェクトの hideChildrenTargets プロパティを使用して、Resize エフェクトの再生中は Panel コンテナの子を非表示にします。hideChildrenTargets プロパティの値は Panel コンテナの Array で、これにアニメーションの再生中にサイズが変化する Panel コンテナを含めます。hideChildrenTargets プロパティを true に設定すると、Flex は Resize エフェクトを再生する前に、この Array を調べ、指定された各 Panel コンテナの子を非表示にします。
多くの場合、開発者は、ビューに、グラデーションや微妙なパターンなどを使用した単色の背景イメージを使用します。エフェクトの実行中に Flash Player で行われる再描画を軽減するために、背景イメージは単色にするようにしてください。単色の代わりにわずかなグラデーションを使用する場合は、SWF ファイルや SVG ファイルの背景イメージを使用してください。標準の JPG や PNG ファイルよりも Flash Player で再描画しやすくなります。
エフェクトのパフォーマンスを向上させるために、エフェクトの継続時間中にアプリケーションのバックグラウンド処理を無効にすることもできます。そのためには、エフェクトの suspendBackgroundProcessing プロパティを true に設定します。無効にできるバックグランド処理には、コンポーネントの測定、レイアウト、およびエフェクトの継続時間中のデータサービスへの応答などがあります。
エフェクトは、Flash Player のビットマップキャッシュ機能を使用して、アニメーションを高速にできます。通常、エフェクトの再生中にターゲットコンポーネントの描画に変更がない場合、エフェクトはビットマップキャッシュを使用します。
UIComponent の cachePolicy プロパティでは、エフェクト再生中のコンポーネントのキャッシュ処理を制御します。cachePolicy プロパティには次の値を設定できます。
CachePolicy.ON
エフェクトターゲットを常にキャッシュに保存します。
CachePolicy.OFF
エフェクトターゲットをキャッシュに保存しません。
CachePolicy.AUTO
Flex にエフェクトターゲットをキャッシュに保存するかどうかを判断させます。これがデフォルト値です。
cachePolicy プロパティは、オブジェクトが再描画領域に含まれていても、変化しない場合に使用すると便利です。再描画領域の詳細については、再描画領域についてを参照してください。
cachePolicy プロパティは、cacheAsBitmap プロパティのラッパーを提供します。詳細については、cacheAsBitmap プロパティの使用を参照してください。
画面上でのオブジェクトの実際のレンダリングには著しく時間がかかることがあります。レンダリング時間を改善すると、アプリケーションのパフォーマンスが劇的に向上することがあります。この節で紹介する方法は、レンダリング速度を改善する上で役立ちます。さらに、前のエフェクトのパフォーマンスの改善で説明した方法を使用すれば、エフェクトのレンダリング速度も向上します。
ラッパーの <object> タグおよび <embed> タグの quality プロパティを使用すると、Flash Player での Flex アプリケーションのレンダリングを変更できます。quality プロパティの有効な値として設定できるのは、low、medium、high、autolow、autohigh、および best です。デフォルト値は best です。
low 設定は画質よりも再生速度を優先し、アンチエイリアスを使用しません。autolow 設定では、まず再生速度を優先しますが、可能な場合は画質も改善します。autohigh 設定は、最初は再生速度と画質の両方を等しく重視しますが、必要に応じて再生速度を優先します。medium 設定では、多少のアンチエイリアスが適用され、ビットマップがスムージング処理されません。high 設定は、再生速度よりも画質を優先し、必ずアンチエイリアスを使用します。best 設定では、最高の画質を実現し、再生速度は考慮されません。すべての出力に対してアンチエイリアスが行われ、ビットマップが常にスムージングされます。
これらの設定の詳細については、object タグと embed タグについてを参照してください。
再描画領域とは、オブジェクトが変更された場合に、再描画が必要となるオブジェクト周囲の領域です。オブジェクトが変更されると、再描画領域内のすべての項目が次のレンダリング工程中に再描画されます。Flash Player で再描画される領域には、オブジェクト、背景やオブジェクトのコンテナなど、再描画領域に重なるオブジェクトなどが含まれています。
デバッガ版の Flash Player では、実行時に再描画領域を確認できます。それには、プレーヤーのメニューで、表示/再描画領域を表示を選択します。このオプションを選択すると、デバッガ版の Flash Player は、アプリケーションの実行中に各再描画領域の周囲に赤い長方形を描画します。
再描画領域を確認すると、アプリケーション実行中の変更内容とレンダリング量を把握できます。Flash Player では、場合によって、いくつかのオブジェクトの再描画領域が 1 つの領域にまとめられて再描画されることがあります。つまり、オブジェクト間の間隔がある程度小さい場合は、個別に再描画するよりも効率がよくなるので、1 つの領域として再描画される可能性があります。領域の数が多すぎる場合、Flash Player では画面全体を再描画することもあります。
レンダリング速度を改善するには、cacheAsBitmap プロパティを慎重に使用してください。このプロパティはどの UIComponent にも設定できます。
cacheAsBitmap プロパティを true に設定すると、Flash Player はオブジェクトの初期ビットマップイメージのコピーをメモリに保存します。後でそのオブジェクトが必要になった場合、Flash Player では、そのオブジェクトのプロパティに変更がなければ、キャッシュされたイメージを使用してオブジェクトを再描画します。この方が、オブジェクトを構成するベクトルを使用するよりも短時間ですむ可能性があります。
特に画面上でのオブジェクトの移動を伴うアニメーションやその他のエフェクトを使用する場合は、cacheAsBitmap プロパティを true に設定すると効果的です。Flash Player では、アニメーション中に各フレームのオブジェクトを再描画するのではなく、キャッシュされたビットマップを使用できます。
ただし、ビットマップとしてキャッシュに保存されたオブジェクトのプロパティの変更には多くの計算処理が必要であるというマイナスの面があります。Flash Player では、キャッシュされたオブジェクトの表示に影響する変更があるたびに、古いビットマップを削除し、新しいビットマップをキャッシュに保存する必要があります。したがって、cacheAsBitmap プロパティを true に設定するのは、大きな変更のないオブジェクトだけにします。
ビットマップキャッシュは、アニメーションの実行中など、必要な場合にのみ有効にします。また、多くのメモリを使用するので、一度に数個のオブジェクトだけに使用します。このプロパティを効果的に使用するには、いったん設定したら二度と変更しないのではなく、オブジェクトのライフサイクルを通じて必要なときにこのプロパティを変更することをお勧めします。
レンダリング速度を改善するため、DropShadowFilter などのフィルタは多用しないでください。フィルタの負荷は、フィルタを適用するオブジェクトに含まれるピクセル数に比例します。このため、フィルタはサイズの小さいオブジェクトに使用するのが最適です。
デバイステキストとベクターグラフィックを組み合わせると、レンダリング速度が落ちることがあります。例えば、テキストとグラフィックの両方がセル内に含まれた DataGrid コントロールの再描画は、テキストだけを含む DataGrid に比べ非常に遅くなります。
オブジェクトの scrollRect および mask プロパティを使用すると、負荷が高くなります。これらのプロパティの使用頻度は、最小限に抑えるようにしてください。
大きいデータセットを操作するときのオーバーヘッドを最小限に抑えることができます。
DataService クラスを使用してリモートデータを取得する場合、初期段階ではクライアント上のコレクションにすべてのデータをロードしないようにすることができます。ページングを使用してデータを処理すると、大量のデータがネットワーク上を移動することによるアプリケーションの低速化を防ぐことができます。段階的に取得するデータのことを「ページング」データ、まだ受信されていないデータのことを「保留」データと呼びます。
DataService クラスを使用したデータのページングには、次のメリットがあります。
詳細については、『Adobe Flex 3 開発ガイド』のデータプロバイダおよびコレクションの使用を参照してください。
大きなデータセットで DataGrid コントロールを使用すると、スクロールバーの使用時にスクロールが遅くなることがあります。DataGrid では、データプロバイダに対する getItemAt() メソッドを呼び出して、新たに表示されるデータを表示します。
デフォルトの DataGrid は、ユーザーがスクロールする間、データを継続的に更新します。つまり、DataGrid が継続的に getItemAt() メソッドを呼び出すことになるので、DataGrid のデータをスクロールするだけでパフォーマンスが低下することがあります。このメソッドの呼び出しでは、コンピュータの負荷が高くなることがあります。
liveScrolling プロパティを false に設定してこの「ライブスクロール」を無効にすると、スクロールが止まったときにだけ表示を更新できます。
liveScrolling プロパティのデフォルト値は true です。TextArea、HorizontalList、TileList、DataGrid など、ScrollControlBase のすべてのサブクラスにはこのプロパティがあります。
コンポーネントを動的に繰り返すという点では、リストコントロールの方が Repeater コントロールよりも優れています。ただし、Repeater を使用しなければならない場合もあるので、このコントロールのパフォーマンスを改善する方法についても説明します。
コンポーネントを動的に繰り返す場合は、Repeater コントロールまたはリストコントロール(HorizontalList、TileList、List など)を使用します。多くの場合、Repeater で生成されるレイアウトの代わりに HorizontalList または TileList とアイテムレンダラーの組み合わせを使用すると、より優れたパフォーマンスを実現できます。
Repeater オブジェクトは、Form コンテナでよく使用される RadioButton コントロールなどの数の少ない単純なユーザーインターフェイスコンポーネントを繰り返す場合に便利です。HorizontalList、TileList、または List コントロールは、より多くのオブジェクトを表示する場合に使用できます。
HorizontalList コントロールを使用すると、HBox コンテナのようにデータが横並びで表示されます。HorizontalList コントロールでは、アイテムは常に左から右に表示されます。TileList コントロールは、Tile コンテナのようにデータをタイル状に並べて表示します。TileList コントロールには、後のアイテムを下または右のどちらに置くかを決定する direction プロパティがあります。List コントロールは、データを 1 列の垂直列に並べます。
Repeater オブジェクトが、繰り返されるすべてのオブジェクトをインスタンス化するのに対して、HorizontalList、TileList、および List コントロールは、リストに表示されているオブジェクトのみをインスタンス化します。Repeater コントロールは、Array に含まれる各エントリについて、子の新しいコピーを生成するデータプロバイダ(一般的に Array)を取ります。遅延インスタンス化を使用しないコンテナ内に Repeater コントロールの子を配置すると、最初に表示されない多くのオブジェクトが生成されることがあります。
例えば、VBox コンテナを使用すると、コンテナが初めて作成されるときに、コンテナに含まれるすべてのオブジェクトが作成されます。次の例では、Repeater コントロールにより、最初に表示されるかどうかに関係なくすべてのオブジェクトが生成されます。
<?xml version="1.0"?>
<!-- optimize/VBoxRepeater.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var imgList:ArrayCollection = new ArrayCollection([
{img:"../assets/butterfly.gif"},
{img:"../assets/butterfly-gray.gif"},
{img:"../assets/butterfly-silly.gif"}
]);
]]></mx:Script>
<mx:Panel title="VBox with Repeater">
<mx:VBox height="150" width="250">
<mx:Repeater id="r" dataProvider="{imgList}">
<mx:Image source="../assets/{r.currentItem.img}"/>
</mx:Repeater>
</mx:VBox>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
それに対して、リストコントロールを使用すると、最初に表示されるリストに含まれるコントロールだけが生成されます。次の例では、リストコントロールでレンダリング用のイメージだけを作成します。
<?xml version="1.0"?>
<!-- optimize/ListItems.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
private static var birdList:Array = ["../assets/butterfly.gif","../assets/butterfly-gray.gif","../assets/butterfly-silly.gif"];
[Bindable]
private var birdListAC:ArrayCollection = new ArrayCollection(birdList);
private function initCatalog():void {
birdlist.dataProvider = birdListAC;
}
]]></mx:Script>
<mx:Panel title="List">
<mx:List id="birdlist" rowHeight="150" width="250" rowCount="1" itemRenderer="mx.controls.Image" creationComplete="initCatalog()">
</mx:List>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
Repeater コントロールを使用するにあたっては、次の点を考慮してください。
繰り返されるインスタンスに古い状態情報が保持されないように、recycleChildren プロパティのデフォルトの値は false です。例えば、Repeater オブジェクトを使用して写真イメージを表示する場合に、それぞれの Image コントロールに、プリントの注文枚数を示す NumericStepper コントロールが関連付けられているとします。イメージなどの状態情報は dataProvider プロパティから得られます。プリント枚数などのその他の状態情報は、ユーザーとのやり取りで設定されます。recycleChildren プロパティを true に設定し、Repeater オブジェクトの startingIndex 値を徐々に増加させて写真間を移動すると、それに応じて Image コントロールが新しいイメージにバインドされますが、NumericStepper コントロールは古い情報を保持したままになります。recycleChildren="false" を使用するのは、状態情報を手動でリセットするのが面倒な場合、または dataProvider プロパティを変更しても Repeater オブジェクトの子の再生成がトリガされないと確信できる場合だけにしてください。
recycleChildren プロパティは、Repeater オブジェクトが最初にロードされるときの Repeater オブジェクトの速度には影響を与えません。recycleChildren プロパティによってパフォーマンスが向上するのは、Repeater コントロールのデータプロバイダに対するそれ以降の変更のみです。Repeater オブジェクトが子を 1 度だけ生成することがわかっている場合は、recycleChildren プロパティを使用する必要はなく、状態情報が古くなることを心配する必要もありません。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート