このマスターシリーズでは、Flash Builder 4.5およびAdobe AIRを使用したFlexモバイルアプリケーションの開発について解説します。

本記事では、モバイル機能を使用したアプリケーション開発におけるパフォーマンスの最適化について解説します。

Sparkコンポーネントの利用

モバイルアプリケーション開発において、Flex 3のMXコンポーネントを利用することは非推奨となっています。なぜなら、MXコンポーネントは、モバイルアプリケーションで使うには処理が重いからです。また、スキンやスタイルについても重い処理が必要とされます。そのため、モバイルアプリケーション開発にコンポーネントを使う場合は、Sparkコンポーネント+モバイル用スキンを使いましょう。

なお例外として、MXチャートコンポーネントはモバイルでも非推奨とはなっておらず、利用することができます。ただし、多くのデータを表示したり、アニメーションを多用したりすることは避けましょう。

それではSparkコンポーネントについて、テーマごとに見ていきましょう。

コンテナ

MXコンポーネントでの代表的なコンテナコンポーネントと言えば、Containerやそれを拡張したCanvasですが、それらのコンテナコンポーネントは生成と各機能の処理が重いため、モバイルアプリケーションで利用することは非推奨となっています。

下表は、MXコンテナコンポーネントの基底クラスとなるContainerクラスの4つの主な機能が、Sparkコンポーネントでは4つのコンテナコンポーネントに分かれていることを示しています。4つのコンテナコンポーネントを必要に応じて使い分けることで、実行する処理を軽くすることができます。

MXとSparkのコンテナの比較
機能 Spark MX
基本的なコンテナ機能 Group、VGroup、HGroup Container
データアイテムの表示と管理機能 DataGroup
スクロール機能 Scroller
境界線や背景の表示機能 SkinnableContainer

画像表示

MXコンポーネントで画像を表示する際には、MX Imageコンポーネントを使用します。ただし、このMX Imageコンポーネントは生成の処理が重いため、モバイルアプリケーションで利用することは非推奨となっています。その代わりに、SparkコンポーネントのBitmapImageコンポーネントを利用します。BitmapImageコンポーネントは、GraphicElementの1つで、生成の処理が軽いところが特徴です。そして、外部ファイルの読み込み/拡大縮小/キャッシュという機能を持っています。

また、Sparkコンポーネントには、Spark Imageという画像表示するためのコンポーネントもあります。このSpark Imageは、画像表示するための部品として上記のBitmapImageを利用しています。また、画像を表示するだけでなく、画像読み込みのプリローダーや、画像が壊れているときのアイコンや境界線を表示する機能もあります。ただし、このようにSpark Imageコンポーネントは多くの機能を持っているため、MX Imageコンポーネントより処理が重くなります。そのため、アイテムレンダラーなどには使用しないように注意しましょう。

さらに、BitmapImageコンポーネントやSpark Imageコンポーネントを使う際に、キューイング機能とキャッシュ機能を併用するとパフォーマンスの向上が見込めます。

 

画像データのキューイングとキャッシュ

画像データのキューイングとは、画像データを外部サーバーやローカルストレージから読み込む処理をキューに入れて順次実行する機能です。これにより、読み込み処理が一斉に実行されることを避けることができ、処理の負荷を分散させることができます。

画像データのキャッシュとは、画像データをキャッシュしておき、画像データを再取得する際にそのキャッシュから利用する機能です。これにより、再取得の処理が高速になり、その結果、画像処理も高速になります。

これらの機能は、spark.core.IContentLoaderを実装したspark.core.ContentCacheというクラスが担っています。利用するためには、Spark ImageとBitmapImageのcontentLoader変数にContentCacheのインスタンスを設定します。次のコードは、ContentCacheを設定した例です(サンプル:01_ImageContentCacheExample.fxp)。

ソースコード:01_ImageContentCache \src\views\HomeView.mxml

<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView" creationComplete="view1_creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; import spark.core.ContentCache; import spark.core.IContentLoader; public static const contentLoader:IContentLoader = new ContentCache(); protected function view1_creationCompleteHandler(event:FlexEvent):void { image.contentLoader = contentLoader; } ]]> </fx:Script> <s:BitmapImage id="image" source="URL"/> </s:View>

テキスト

MXのテキストコンポーネントやText Layout Framework(TLF)は、モバイルアプリケーションで利用することは非推奨となっています。その代わりにSparkのテキストコンポーネントを利用します。Sparkテキストコンポーネントのパフォーマンスは、プラットフォームに依存します。

Sparkテキストコンポーネントのクラス
クラス 機能
StyleableTextField 選択・編集可能な文字列を表示するためのテキストコンポーネント。モバイルアプリケーション開発では、TextInput and TextAreaの部品として使われています。MXMLに記述することはできません。
Label 静的な文字列を表示するためのテキストコンポーネント。
RichText 複数行の静的な文字列を表示するためのテキストコンポーネント。
RichEditableText 複数行の選択・編集可能な文字列を表示するためのテキストコンポーネント。通常のアプリケーション開発では、TextInputとTextAreaの部品として使われています。

グラフィックス

MXコンポーネントでは、UIComponentを使ってグラフィックスを描画しています。また、フォーカス/ステート/スタイルなどで描画する際に、graphics.drawRectなどを使っています。モバイルアプリケーションでは、目的に応じてGraphicElementやFXGを利用してグラフィックスの描画を行います。

GraphicElement

GraphicElementは、動的に描画を行うために利用します。線/矩形/円/パス/画像などのサブクラスを利用して描画し、線の色/太さ/塗りなどを動的に変更することができます。また、GraphicElementを使った描画は、親となるビジュアルオブェクトに描画します。そのため、複数のGraphicElementがある場合でも、親となるビジュアルオブェクトが共通の親ビジュアルオブェクト1つになるので処理が軽くなります。

モバイルアプリケーションの場合、GraphicElementは画面やレンダラーでこれらクラスを利用します。

FXG

FXGは、変更頻度の低い静的なグラフィックスを扱うために利用します。FXGはXMLで記述し、コンパイル時にグラフィックスが描画されたビジュアルオブジェクトになります。つまり、実行時にGraphicElementのような動的な描画処理を行いません。FXGはベクター形式で描画されているので、拡大しても荒れることがありません(ビットマップ画像を使った場合は例外です)。また、FXGをリサイズしないのであれば、cacheAsBitmapをtrueにすることもできます。

モバイルアプリケーションの場合、FXGはレンダラーやSparkコンポーネトのモバイルスキンなどで利用します。

アイテムレンダラー

Spark DataGroupやListなどのコンポーネントは、データごとにアイテムレンダラーを生成してレイアウトを行います。複数のデータがある場合にはアイテムレンダラーも複数になるので、生成とレイアウトの処理を軽くする必要があります。また、アイテムレンダラーは、MXMLとActionSctiptで作成することができます。

MXMLアイテムレンダラー

MXMLでアイテムレンダラーを作成すると、素早くシンプルに作成することができます。しかし、処理が重くならないように、以下のように最適化して作成する必要があります。

  • ItemRendererを利用して作成する。
  • 処理の重いコンポーネントを使用しない。
  • テキスト表示にはLabelを利用する。
  • 画像ファイルの読み込みには、BitmapImageコンポーネントを利用する。
  • BitmapImageコンポーネントにはspark.core.ContentCachを設定する。
  • 頻繁に描画されるが、変更の少ない画像やグラフィックには「cacheAsBitmap ="true"」を指定する。
  • アイテムレンダラー自身に「opaqueBackground="0xFFFFFF"」と「cacheAsBitmap="true"」を指定する。
  • 必要がなければ、autoDrawBackgroundをfalseに設定する。
  • グループのネストは少なくする。

次のコードは、ItemRendererのカスタム例です(サンプル:02_ItemRendererExample.fxp)。

ソースコード:02_ItemRendererExample\src\renderer\ MyRendererMXML.mxml

<?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:assets="assets.*" opaqueBackground="0xFFFFFF" cacheAsBitmap="true" width="100%"> <fx:Script> <![CDATA[ import spark.core.ContentCache; public static const cc:ContentCache = new ContentCache(); ]]> </fx:Script> <s:HGroup verticalAlign="middle" left="0" right="0" gap="10" paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"> <s:BitmapImage id="icon" source="{data.icon}" contentLoader="{cc}"/> <s:Label width="100%" text="{data.name}"/> <assets:Arrow cacheAsBitmap="true"/> </s:HGroup> <s:Line width="100%"> <s:stroke><s:SolidColorStroke color="0" weight="1"/></s:stroke> </s:Line> </s:ItemRenderer>

ActionScriptアイテムレンダラー

ActionScriptで作成されたIconItemRendererとLabelItemRendererは、上記の最適化を応用して作成されているアイテムレンダラーです。これをベースにアイテムレンダラーをカスタムすることで、MXMLアイテムレンダラーよりも処理を軽くすることができます。

次のコードは、IconItemRendererのカスタム例です(サンプル:02_ItemRendererExample.fxp)。

ソースコード:02_ItemRendererExample\src\renderer\MyItemRendererAS.as

package renderer { import assets.Arrow; import spark.components.IconItemRenderer; public class MyItemRendererAS extends IconItemRenderer { public function MyItemRendererAS() { labelField="name"; iconField="icon"; decorator=assets.Arrow; opaqueBackground=0xFFFFFF; cacheAsBitmap=true; } } }

※アイテムレンダラーの詳細については、「第5回 Flexモバイルアイテムレンダラーの紹介」をご覧ください。

モバイルスキン

Sparkコンポーネントでは、モバイルアプリケーション用のモバイルスキンを利用します。モバイルスキンは、デスクトップアプリケーションのスキンと異なります。既存のモバイルスキンは、前述のMXMLアイテムレンダラーでの最適化を応用して作成されています。デスクトップとモバイルにおけるスキンの相違点を下表にまとめました。

デスクトップとモバイルのスキン作成の相違点
機能 デスクトップ モバイル
描画処理 GraphicElements コンパイル済みFXG
スキン拡張 MXMLでSkinを利用 <s:Skin> ActionScriptでMobileSkinを継承
class ButtonSkinBase extends MobileSkin
テキスト Labelを利用 StyleableTextFieldを利用

ボタンを例にとると、ボタンのモバイルスキンはActionScriptで実装されています。

public class ButtonSkin extends ButtonSkinBase

ボタンのラベルは、Labelの代わりにStyleableTextFieldを使っています。

public var labelDisplay:StyleableTextField;

ボタンのアップとダウンのステートの描画は、FXGを指定しています。

upBorderSkin = spark.skins.mobile320.assets.Button_up; downBorderSkin = spark.skins.mobile320.assets.Button_down;

おわりに

モバイルアプリケーション開発におけるパフォーマンスの最適化について解説しました。モバイルアプリケーションはデスクトップの処理能力とは異なるので、処理の速度を意識して設計・開発する必要があることが理解できたかと思います。

今後、モバイルでも高スペックなハードウェアが登場して処理能力は向上すると予測されますが、常にパフォーマンスの最適化を行ってよりよいモバイルアプリケーションを開発していきましょう。

以上、全6回にわたってFlex 4.5モバイル機能を使ったアプリケーションの開発について、基礎から実践的なノウハウ、そしてパフォーマンスの最適化についてまで解説してきました。本連載はこれで終了しますが、モバイルアプリケーション開発時には、再度このマスターシリーズを参考にしていただけたらと思います。

関連記事