引き続き Optimizing Performance for the Flash Platform から、CPU の使用率を削減するための Tips です。
最初は、デバイス上での Flash Player 10.1 の新機能 3 点です。
スリープモード
- Flash Player 10.1 はアプリケーションが中断されたことを検知するとスリープモードになる
- スリープモードではフレームレートが 4 fps になり、描画は行われない
- スリープモード中はイベントが発生しない
- AIR にはスリープモードは無い
ポーズとレジューム
- Flash Player 10.1 はコンテンツがスクリーン上に表示されない状態になると再生を停止 (ポーズ) し、表示されると再生を再開 (レジューム) する
- ポーズ時には積極的にメモリの開放も行われる
- ポーズが起きるのはコンテンツがページのスクロールなどにより完全に表示されない状態になったとき
- ポーズ状態でも映像と音声の再生は継続する (ただし描画は行われない)
- hasPriority = true を設定 (下の項目参照) すると、ポーズ状態でも ActionScript の実行が行われる
- この機能も AIR には無い
hasPriority
- 新しい HTML 属性 <param name="hasPriority" value="true" />
- 値を true にすると、例えばページの下にの方にあってスクロールしないと表示されないようなコンテンツが、表示されないままでも読み込み後直ぐに再生が開始されるようになる
- ただし、表示されていないコンテンツの場合、再生されても描画は行われない
- CPU に余裕が無いとき、この属性の値に係わらず、コンテンツをクリックしないと再生を開始しない (クリック・トゥー・プレイとよばれる機能)
さて、以下は、CPU リソースを効率的に使うための Tips です。Flash Player 10 以前のバージョンにも適用されます。
オブジェクトの停止
- MovieClip をディスプレイリストから削除しても、ガーベジコレクションにより削除されるまでは Event.ENTER_FRAME など CPU を消費するコードが実行される
- そのため、Event.REMOVED_FROM_STAGE と Event.ADDED_TO_STAGE イベントを利用する
- 例えば下のようなコードを追加
// Event.ADDED_TO_STAGE と Event.REMOVED_FROM_STAGE イベントを取得する myMovieClip.addEventListener(Event.ADDED_TO_STAGE,activate); myMovieClip.addEventListener(Event.REMOVED_FROM_STAGE,deactivate); function activate(e:Event):void { // イベントの開始/再開 e.currentTarget.addEventListener(Event.ENTER_FRAME,handleMovement); } function deactivate(e:Event):void { // イベントの生成とタイムライン再生を停止 e.currentTarget.removeEventListener(Event.ENTER_FRAME,handleMovement); e.currentTarget.stop(); }
- Loader クラスを使用して読み込んだ SWF を開放する場合、SWF 中のすべての MovieClip を停止させるべき
- Flash Player 10 から追加された Loader.unloadAndStop() メソッドは、SWF 中の全てのオブジェクトを停止しガーベジコレクターを強制的に実行させる
- unloadAndStop() は、その他にも以下の作業を行う: 音声再生の停止、メインのタイムラインからイベントリスナーの削除、Timer の停止、カメラやマイクの開放
var loader:Loader = new Loader();
loader.load ( new URLRequest ( "content.swf" ) );
addChild ( loader );
stage.addEventListener ( MouseEvent.CLICK, unloadSWF );
function unloadSWF ( e:MouseEvent ):void
{
// unload() ではなくこちらを使う
loader.unloadAndStop();
}
マウスインタラクション
- マウスインタラクションの対象のオブジェクトを検出する時に CPU リソースを消費する
- マウスインタラクションの不要なオブジェクトの関連機能を無効にすることで、処理を効率化することができる
- mouseEnabled 属性の使用
mySprite.mouseEnabled = false;
- mouseChildren 属性の使用
var container:Sprite = new Sprite(); for ( var i:int = 0; i< 10; i++ ) { container.addChild( new Sprite() ); } // 全ての子オブジェクトのマウスインタラクションを無効に container.mouseChildren = false;
Timer と ENTER_FRAME イベント
- ENTER_FRAME イベントは毎フレーム変更されるもの (アニメーションなど) を扱う場合に向く
- Timer はより長い時間一定の間隔でコードを実行したい場合に向く
- TimerEvent.updateAfterEvent() メソッドを呼ぶことで、Flash Player に画面の更新を指示できる
- タイマーも ENTER_FRAME イベントも状況によって (例えば CPU 負荷の高い環境とか) 呼び出し間隔の精度が悪くなることがある
- 複数のオブジェクトに ENTER_FRAME イベントハンドラーを登録する代わりに、一箇所にまとめたほうが実行されるコードを削減できることがある。また、管理が楽になる
- Timer オブジェクトの数はできるだけ少なく。同じ間隔のものはまとめるとか間隔が整数倍のものは条件文で制御するなどの工夫をする
- 使用されない Timer オブジェクトは stop() メソッドで停止しておく
- タイマーイベントや ENTER_FRAME イベントによる画面更新は最小限にする
- デバッグプレーヤーではコンテキストメニューから再描画領域を表示させることができる
- flash.profiler.showRedrawRegions() メソッドを使っても再描画領域を表示させることができる
コメントする