构件性能优化,高效的AIR应用程序 之Framerate 细节处理
如何构件性能优化,高效的应用程序无论利用那种技术,都会是一个复杂的问题,尤其是构件大型的应用,会有很多影响到系统性能,效率的因素。比如,程序的架构是否合理,是否有冗余逻辑造成效率降低,核心算法是否优化,是否关注代码细节的合理处理,等等,很多适用于其他技术的经验,方法也应该适用于构建 AIR 应用程序。那么,有没有一些针对AIR 应用程序相对特殊的地方呢?
首先引入一个概念,帧频(Framerate)。我们都知道电影,动画都是一帧一帧的播放的,通常以每秒 24 帧作为一个基础,因为这是适合人类视觉感光频率的,当然在高清,流媒体等应用领域帧频会不同于这个值。我们所构建的基于 flash 的 AIR 应用程序都基于这个原理,即便看似不变的界面也是一帧一帧渲染出来的,系统默认设置值也是 24 帧每秒。毋庸置疑,每渲染一帧,都会消耗一定 CPU, 内存资源。
Framerate 在 flash/AIR 应用中的位置就像心脏在我们身体中一样,同一个人,在安静或睡眠时心率减慢,运动时或情绪激动时心率加快。人必须保持的保持在一个合理的心率范围,就像美洲豹如果以时速 120 公里追赶猎物,超过 30 秒还没有抓到的情况下就必须止步放弃一样,长时间高速运转就会给身体带来损害。 Framerate 道理也是一样,如果长时间维持在一个高帧频率必定会带来额外的系统消耗。
Arno在他的博客中提出了几个最佳实践,归为以下几点:
1 ,尽量使用低的帧频率
2 ,动态设置帧频率已适应动画渲染需要
3 ,不再必须的情况下不要使用 Event.ENTER_FRAME handler
4 ,尽量介绍少用 Event.ENTER_FRAME 和Timer 的个数
对于以上几点可以再做出以下补充解释:
1 ,如果你所构建的应用程序是以数据驱动 , 实现商务逻辑为主,并且展现层上没有特别多的动画, transition, 或是 effect, 可考虑降低整体帧频率,如设置为 7 帧每秒,正常情况下,可降低 CPU 1%- 5% ( 在我的 MAC 上已证实 ) 。 同时,如果应用程序的 user interaction 不是很多的情况下,当应用程序处于AIREvent.APPLICATION_DEACTIVATE 时,降低帧频率至 0 ,也可大大降低 CPU 使用率。
如果有 Video playback, 或是大量 animation 的时候,可考虑设置一个开关机制,需要的时候开启开关,动态把帧频设高,播放完毕后再恢复省资源模式。
2 ,如果在不同的 timer 中,能找到之间的逻辑关系,则减少独立 timer 的个数,用逻辑去实现与之相关联 timer 的触发。
3 ,我在调试过程发现可设置一个用 timer 检测的简易可视帧频率,这样能科学验证,且心理看得踏实,代码如下供参考:
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml " layout="absolute" creationComplete="init()" width="320" height="480" verticalScrollPolicy="off" horizontalScrollPolicy="off" borderStyle="none" showGripper="false" showStatusBar="false" showFlexChrome="false" backgroundColor="#FFFFFF"> <mx:Script> <![CDATA[ import mx.events.AIREvent; private var fpsCounter : uint; private var timer : Timer; public static const ACTIVE:int = 24; public static const INACTIVE:int = 1; private function init() : void { timer = new Timer(1000); timer.addEventListener( TimerEvent.TIMER, onTimerEvent ); timer.start(); fpsCounter = 0; this.addEventListener(Event.ENTER_FRAME, onFrameEnter); this.addEventListener(AIREvent.APPLICATION_DEACTIVATE,onDeactivate); this.addEventListener(AIREvent.APPLICATION_ACTIVATE,onActive); } private function onActive(event: Event):void { this.stage.frameRate = ACTIVE; setFPS.text = Math.round(stage.frameRate).toString() + " fps"; } private function onDeactivate(event: Event):void { this.stage.frameRate = INACTIVE; setFPS.text = Math.round(stage.frameRate).toString() + " fps"; } private function onFrameEnter( event : Event ) : void { fpsCounter++; trace("enterframe"); } private function onTimerEvent( event : Event ) : void { curentFPS.text = fpsCounter.toString()+ " fps"; fpsCounter=0; } public function changeFrameRate(delta:Number):void { stage.frameRate = stage.frameRate + delta; setFPS.text = Math.round(stage.frameRate).toString() + " fps"; } ]]> </mx:Script> <mx:Image id="logo" source="@Embed(source='assets/logo.jpg')" y="195" x="102"/> <mx:Button id="decreaseButton" x="27" y="329" label="-" width="67" height="74" fontSize="60" click="changeFrameRate(stage.frameRate > 20 ? -5 : -1);"/> <mx:Label text="Current FPS" color="#797979" width="105" textAlign="center" fontSize="14" x="37" y="177" fontWeight="bold"/> <mx:Label text="24 fps" color="#797979" width="96" textAlign="center" fontSize="14" x="167" y="177" id="curentFPS"/> <mx:Button id="increaseButton" x="217" y="329" label="+" width="74" height="74" fontSize="60" click="changeFrameRate(stage.frameRate >= 20 ? 5 : 1);"/> <mx:HBox height="40" verticalAlign="middle" bottom="0" left="0" right="0" horizontalAlign="center" horizontalGap="0"> </mx:HBox> <mx:Label text="Set FPS" color="#797979" width="96" textAlign="center" fontSize="14" x="26" y="149" fontWeight="bold"/> <mx:Label text="24 fps" color="#797979" width="96" textAlign="center" fontSize="14" x="167" y="150" id="setFPS"/> <mx:TextArea x="10" y="10" width="300" color="#797979" height="78" borderStyle="none" fontSize="14"> <mx:text>Compare the CPU usage of this application when it is in different FPS setting.</mx:text> </mx:TextArea> </mx:WindowedApplication>
4 ,还有很多影响 AIR 性能效率的小细节 如 number of display objects on stage (http://bugs.adobe.com/jira/browse/FP-1149) 等等。欢迎大家一起来探讨!
-瓶子