誕生背景
Adobe的Flash編譯器(ASC, ActionScript Compiler)表現得實在太“昨天”了,加上Flash虛擬機在性能上還有很大的提升空間,Flash很多時候被當做玩具或者被戲稱為CPU hog。一般來說,我們很少會手去工優化一個SWF,大多數情況下,它都能良好地運行,但是當一個SWF文件尺寸過大導致加載時間過長或者代碼執行時間過長導致幀頻過低時,我們就需要考慮對SWF進行優化了,例如代碼的精簡,靜態資源(圖片、視頻等)的壓縮。但是手動優化產生的性能提升很是有限,更多的優化任務本應該交給編譯器來完成的,值得感激的是, Apparat 框架可以幫助我們從手動優化的噩夢中解脫出來,不僅如此,任何未經過優化的SWF都能從中得到優化。Apparat的作者 joa ebert 在Flash性能優化領域有深刻見解,今年的 FlashAndTheCity 大會上,joa的出色工作為他贏得了 “2010年最天才的Flash開發者”和“2010年最杰出的貢獻者” 兩項大獎。
搭建環境
Apparat框架通過Scale寫成,在實踐它之前,需要先安裝Scala 2.8.0,Java 1.6,另外 7-zip 的安裝是可選的。搭建好這些基本的運行環境后(需要加入到PATH環境變量中),從 Google Code 可下載最新的安裝包(目前是1.0RC8)。下載后解壓到新的文件夾,其中包含的文件有:
Apparat提供了很多命令行工具,比如tdsi, stripper, reducer等等,還有一些非常特殊的ActionScript API(存在于SWC文件中)。接下來我們來看看Apparat是如何為Flash提速的。
優化字節碼
Apparat的核心功能是TAAS(Three Address ActionScript Compiler),TAAS不會改變任何一行ActionScript,它僅是使用普通的優化技術就能獲得可觀的性能提升。不同于Adobe的編譯器ASC,Apparat是對編譯過的SWF和SWC文件進行分析,再組織和再裝配。
Flash虛擬機AVM中的字節碼是基于堆棧的,這種結構難以再被優化,Apparat把基于堆棧的字節碼先轉換成 CFG(Control Flow Graph) ,然后再通過CFG轉換成無堆棧的 TAC(Three Address Code) 碼, 即TAAS(Three Address ActionScript)。
有了TAC/TAAS, 就可以根據編譯器優化技術對Flash的字節碼進行再度優化了,例如 inline expansion , copy propagation , constant folding , dead code elimination 等等。
Apparat提供了幾個有用的SWC文件,它們擁有更加高效的API,甚至也包含了ActionScript還無法使用的Alchemy API。使用了這些API的SWF經過Apparat處理之后,執行效率要大大提升,其原理是Apparat對相應的代碼做了內聯(inline)優化。優化字節碼的命令格式是:
tdsi -i input.swf -o output.swf
去除debug信息
Stripper命令可以去除SWF中所有的debug信息,并且該移除方式是安全的,即不會產生 side effect ,比如代碼:
trace("the next element is: " + iter.next());
經過Stripper之后會變成:
(iter.next());
Stipper的命令格式是:
stripper -i input.swf -o output.swf
壓縮SWF
Reducer命令可以對嵌入在SWF中的PNG圖片進行JPEG有損壓縮,通常對PNG圖片進行100%品質的JPEG壓縮還能節省一定的文件存儲空間。該命令中有參數-q可以來設置壓縮質量,1.0表示最高的壓縮品質,0.0表示最低的壓縮品質。
reducer -i input.swf -o output.swf -q 0.8
如果Reducer通過環境變量能找到 7-zip , Reducer將會利用7-zip做進一步的壓縮,那么即使SWF中不包含圖片我們也能從此命令中獲得一些優化的余地,需要說明的是,目前此功能只能作用于SWF,對SWC文件無效。
Adobe使用 Deflate 壓縮算法對SWF進行壓縮,通過Reducer可以采用更先進的 LZMA 壓縮算法,由于Flash Player不認識LZMA,所以經過LZMA壓縮后的SWF被嵌入在另一個新的SWF中,新的SWF作為一個殼包含了原有的SWF以及一個運行時解碼器,目前這個解碼器大概在5KB左右。使用LZMA壓縮也可以看做是做了(較弱的)代碼混淆。
在使用Reducer命令時加上參數-l可以啟用LZMA壓縮:
reducer -i input.swf -o output.swf -l
除了壓縮圖片,Reducer還對代碼進行了合并,當鏈接外部的SWC時,每一個ABC文件都擁有一個常量池,Reducer能把所有的常量池合并成一個,并且它還對常量進行了排序,這樣頻繁使用的常量會具有更小的開銷。
經過我的測試與實踐,使用Reducer過程中有幾點需要注意:
- 使用JPEG壓縮后的Flash可能在低版本的Flash Player上呈現異樣的色調,所以壓縮后需要在低版本的Flash Player上進行檢測。
- 啟用LZMA很難達到文件尺寸的進一步減少,通常是增加了5KB,而且經過LZMA壓縮的SWF只能運行的Flash Player 10及其以上版本上。
其它
以上3個命令是主要是針對SWF,SWC做進一步的優化,包括程序執行時間的優化,圖片尺寸的優化,SWF存儲空間的優化,以及debug信息的清除。Apparat還包含其它一些有趣的功能,比如dump命令用來分析SWF中的標簽以及輸出UML圖,jitb命令可以把SWF轉換成Java字節碼從而運行在JVM上(還在完善當中)。
?
原文: http://ued.koubei.com/?p=1296
<script id="finspector_js_injector" type="text/javascript"></script>
<script type="text/javascript"></script>
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

