flex 優化技巧 收集[提升性能]
2024-09-12 17:51:10
供稿:網友
1、當創建一個數組的時候避免用new操作符,用 var a:Array = [];而不用var a:Array = new Array();
2、快速的復制一個數組:
var copy : Array = sourceArray.concat ();
3、設置一個數組的值是非常忙的:
employees.push ( employee ); employees[2] = employee;
4、從一個數組中取得值的速度是設置一個數組值的兩倍快:
var employee : Employee = employees[2];
5、當不需要一個類的實例的時候盡量用靜態的屬性或方法:
StringUtils.trim( "text with space at end " );
Class definition: package {
public final class StringUtils {
public static function trim( s : String ) : String {
var trimmed : String ; // implementation...
return trimmed;
}
}
}
6、在整個程序的生命周期中都不會改變的變量用const定義常量:
public const APPLICATION_PUBLISHER : String = "Company, Inc. ";
7、當一個類不需要有子類的時候應該將該類聲明為final類型的:
public final class StringUtils
8、變量和方法的長度在As3中并不影響什么性能,但在別的語言中可能就有影響: someCrazyLongMethodNameDoesntReallyImpactPerformanceTooMuch();
9、將語句寫在一行上面并不會影響AS3程序的性能,但在別的語言中卻有影響:
var i=0; j=10; k=200;
10、在內存占用上面if語句和switch語句并沒有什么區別:
語句:
if ( condition ) {
// handle condition
}
和語句:
switch ( condition ) {
case "A ": // logic to handle case A break ;
case "B ": // logic to handle case B break ;
}
占用的內存是一樣的.
11、當你的程序處理分支較多的時候,你應該適當的排列他們出現的順序,可以參照以下的方式進行:
if ( conditionThatHappensAlot ) {
//處理經常發生的業務邏輯
} else if ( conditionThatHappensSomtimes ) {
// 處理偶爾會發生的業務邏輯
} else {
// 處理幾乎不會發生的情況
}
12、Actionscript虛擬機(Flash Player)推薦在循環內部用int而不是number,但是flash Player10在flash Player9的基礎上做了很多的改進,int,uint和number之間的轉換不在像以前那么慢了。
13、每個變量都應該聲明一個確定的類型,解決那些沒有指定類型的警告信息活錯誤信息。
14、盡量少用unint,它可能會非常慢,但是Flashplayer10做了改進,速度不像以前那么慢了:
var footerHex : uint = 0x00ccff;
15、循環遍歷的時候用int類型:
for (var i: int = 0; i < n; i++)
而不用:
for (var i: Number = 0; i < n; i++)
16、在用decimal的時候用number而不用int:
var decimal : Number = 14.654;
而不用:
var decimal : int = 14.654;
17、用乘法代替除法:
用100*0.01代替100/100
18、在for和while循環中用到的計算應事先聲明好,而不是在循環中重復聲明.
for (..){ a * 180 / Math .PI ; } 應該在循環的外部申明: toRadians = a*180/Math .PI ;
19、避免在循環中調用方法或計算:
var len : int = myArray.lengh; for (var i=0;i<len;i++){}
而不要用:
for (var i=0;i< myArray.lengh;i++){ }
20、用正則表達式進行字符串的校驗,用String的方法進行字符串的查找:
// postal code validation example using regular expressions
private var regEx:RegExp = /^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$/i;
private function validatePostal( event : Event ) : void {
if ( regEx.test( zipTextInput.text ) ) {
// handle invalid input case
}
}
// search a string using String methods
var string : String = "Search me ";
var searchIndex : int = string.indexOf ( "me " );
var search : String = string.substring ( searchIndex, searchIndex + 2 );
21、重復使用諸如DisplayObjects和URLLoaderReuse之類的物體,以保持"內存平穩".
22、使用組件或創建自定義組件時應遵循Flex的組件模型,如下面的方法為組件創建時應先后調用的方法.
createChildren(); commitProperties(); updateDisplayList();
23、盡量少用dataGrid這樣的重量級的組件,除非你用一個常規的list無法實現你要的功能。
24、避免用Repeater 控件創建scrollable數據.
25、盡量避免使用setStyle()方法,這個方法在Flex框架里面是眾多代價敖貴的方法之一。
26、當你用過多的容器嵌套的時候會較低應用程序的性能:
<mx:Panel>
<mx:VBox>
<mx:HBox>
<mx:Label text ="Label 1 " />
<mx:VBox> <mx:Label text ="Label 2 " />
</mx:VBox>
<mx:HBox>
<mx:Label text ="Label 3 " />
<mx:VBox>
<mx:Label text ="Label 4 " />
</mx:VBox>
</mx:HBox>
</mx:HBox>
</mx:VBox>
</mx:Panel>
27、沒有必要每次都用容器組件作為你自定義組件的父控件:
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml " source="avatar.jpg " width ="200 " height ="200 " />
28、減少不必要的容器嵌套
29、不要在Panel中vBox和HBox,用Panel的Layout屬性就可以了
30、不要在application標簽下用HBox,和Vbox,道理和29一樣
31、設置recycleChildren為true來提高Repeater的性能 (重用已經創建過的children而不是重新創建一個新)
<mx:Script>
<![CDATA[
[Bindable]
public var repeaterData : Array = ["data 1 ", "data 2 "];
]]>
</mx:Script>
<mx:Repeater id="repeater " dataProvider="{repeaterData} ">
<mx:Label text ="data item: {repeater.currentItem} "/>
</mx:Repeater>
32、將應用程序的幀率設置為60fps或者更低:
<?xml version ="1.0 " encoding="utf-8 "?>
<mx:Application xmlns:mx=http://www.adobe.com/2006/mxml frameRate="45 ">
</mx:Application >
33、避免每一幀進行過多的顯示操作.
34、能用ENTER_FRAME事件就不用Timer事件.
public function onEnterFrame ( event : Event ) : void { }
private function init () : void {
addEventListener( Event.ENTER_FRAME, onEnterFrame );
}
而不用:
public function onTimerTick( event : Event ) : void { }
private function init () : void {
var timer : Timer = new Timer();
timer.start ();
timer.addEventListener( TimerEvent.TIMER, onTimerTick );
}
35、在多幀上面通過以下方式延遲物體的創建.
<mx:Container creationPolicy="queued "/>
36、Alpha = 0并不是visible = false (設置為invisible的物體會被忽略,不作任何處理)
loginButton.visible = false ;
而不用:
loginButton.alpha = 0;
37、性能優化:
內存釋放優化原則
1. 被刪除對象在外部的所有引用一定要被刪除干凈才能被系統當成垃圾回收處理掉;
2. 父對象內部的子對象被外部其他對象引用了,會導致此子對象不會被刪除,子對象不會被刪除又會導致了父對象不會被刪除;
3. 如果一個對象中引用了外部對象,當自己被刪除或者不需要使用此引用對象時,一定要記得把此對象的引用設置為 null;
4. 本對象刪除不了的原因不一定是自己被引用了,也有可能是自己的孩子被外部引用了,孩子刪不掉導致父親也刪不掉;
5. 除了引用需要刪除外,系統組件或者全局工具、管理類如果提供了卸載方法的就一定要調用刪除內部對象,否則有可能會造成內存泄露和性能損失;
6. 父對象立刻被刪除了不代表子對象就會被刪除或立刻被刪除,可能會在后期被系統自動刪除或第二次移除操作時被刪除;
7. 如果父對象 remove 了子對象后沒有清除對子對象的引用,子對象一樣是不能被刪除的,父對象也不能被刪除;
8. 注冊的事件 如果沒有被移除不影響自定義的強行回收機制,但有可能會影響正常的回收機制,所以最好是做到注冊的事件監聽器都要記得移除干凈。
9. 父對象被刪除了不代表其余子對象都刪除了,找到一種狀態的泄露代碼不等于其他狀態就沒有泄露了,要各模塊各狀態逐個進行測試分析,直到測試任何狀態下都能刪除整個對象為止。
內存泄露舉例 :
1. 引用泄露:對子對象的引用,外部對本對象或子對象的引用都需要置 null ;
2. 系統類泄露:使用了系統類而忘記做刪除操作了,如 BindingUtils.bindSetter() , ChangeWatcher.watch() 函數 時候完畢后需要調用 ChangeWatcher.unwatch() 函數來清除引用 ,否則使用此函數的對象將不會被刪除;
類似的還有 MUSIC , VIDEO , IMAGE , TIMER , EVENT , BINDING 等。
3. 效果 泄露:當對組件應用效果 Effect 的時候,當本對象本刪除時需要把本對象和子對象上的 Effect 動畫 停止掉,然后把 Effect 的 target 對象置 null; 如果不停止掉動畫直接把 Effect 置 null 將不能正常移除對象。
4. SWF 泄露:要完全刪除一個 SWF 要調用它的 unload() 方法并且把對象置 null;
5. 圖片泄露:當 Image 對象使用完畢后要把 source 置 null;( 為測試 ) ;
6. 聲音、視頻 泄露 : 當不需要一個音樂或視頻是需要停止音樂,刪除對象,引用置 null;
內存泄露解決方法:
1. 在組件的 REMOVED_FROM_STAGE 事件回掉中做垃圾處理操作(移除所有對外引用(不管是 VO 還是組件的都需要刪除),刪除監聽器,調用系統類的清除方法)
先 remove 再置 null, 確保被 remove 或者 removeAll 后的對象在外部的引用全部釋放干凈 ;
2. 利用 Flex 的性能優化工具 Profile 來對項目進程進行監控,可知道歷史創建過哪些對象,目前有哪些對象沒有被刪除,創建的數量,占用的內存比例和用量,創建過程等信息 ;