標籤:
雖然iPhone的機能越來越好,但是app的功能也越來越複雜,效能從來都是移動開發的核心關注點之一。我們說一個app效能好,不是簡單指感覺運行速 度快,而應該是指應用啟動快速、UI反饋響應及時、列表滾動操作流暢、記憶體使用量合理,當然更不能隨隨便便Crash啦。工程師開發應用時除了在設計上要避 免效能“坑”的出現,在實際遇到“坑”時也要能很快定位原因所在。定位效能問題原因當然不能靠猜,合理的方法是使用工具測量評估出投資回報最高的問題點, 然後再加以最佳化。
啟動時間
Resume 10秒 Suspend 10秒 Quit 6秒Background Task 10分鐘
123 |
CFAbsoluteTime StartTime;int main(int argc, char **argv) { StartTime = CFAbsoluteTimeGetCurrent();
|
application:didFinishLaunchingWithOptions中添加:
dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@”Lauched in %f seconds.”, (CFAbsoluteTimeGetCurrent() – StartTime)); });可能你會覺得為什麼這樣可拿到系統啟動的時間,因為這個dispatch_async中提交的工作會在app主線程啟動後的下一個run lopp中運行,此時app已經完成了載入並且將要顯示第一幀畫面,也就是系統會運行到`-[UIApplication _reportAppLaunchFinished]`之前。是用Instruments工具Time Profiler跑的調用棧,Instruments的使用方法建議看WWDC中與performance相關的[session錄影](https://developer.apple.com/videos/wwdc),文字寫起來太單薄不夠直觀哈。
[UIApplication _reportAppLaunchFinished]之前完成了系統回調application:didFinishLaunchingWithOptions。
WWDC 2012 Session 235):
2)UIKit初始化:如果應用的Root View Controller是由XIB實現的,也會在啟動時被初始化。
application:didFinishLaunchingWithOptions
-[UIApplication _resportAppLaunchFinished]中調用CA::Transaction::commit實現第一幀畫面的繪製。如果你的程式啟動很慢,能 做的首先是將與顯示第一屏畫面無關的操作放到之後執行;如果是用XIB檔案load第一屏,XIB檔案中的View層也要如果扁平,不要有太多圖層。
如何能夠讓使用者覺得你的app響應迅速呢?當然是app使用者所觸發的操作都能得到立刻響應,即使用者事件(User Event)能夠被主線程的run loop及時處理。什麼是run loop?可以想象成一個處理事件的select多工。主線程中的run loop當然主要是為了處理使用者產生的事件啦,例如點擊、滾動等。以後我們會詳細聊聊run loop這個讓人迷惑的東東。
記憶體問題從來都是iOS app的老大難問題,搞不好程式就爆了。由於iOS系統沒有Swap檔案(知道為啥不?留給懸念),在記憶體不足時會將唯讀資料(例如code page)從記憶體中移出,需要的時候再從disk上讀如記憶體;可讀寫資料不會被系統從記憶體中移出,然而如果佔用的記憶體達到一個閾值,系統會發出相應的通知 和回調讓應用release對象以回收記憶體,如果仍然不能減少記憶體使用量量,系統會直接關閉應用。尤其是iOS 5.0之後,如果你的app收到了memory warning,那麼腦袋也是和其他app一樣放在了案板上,隨時有可能被kill掉,並不是說一定會先Kill掉在背景app。
+[NSobject alloc]/malloc),還會有更多使用記憶體的地方,比如代碼和全域資料(TEXT和DATA),線程棧,圖片,view 的layer backing store等等。因此處理記憶體問題,絕不僅僅是我們開發app時盡量少申請記憶體那麼簡單。
另一種嚴重的記憶體使用量問題是引用了已經釋放的記憶體,直接導致應用崩潰,而Allocation有一個選項Enable NSZombie detection能夠在應用使用已經釋放的記憶體時標註出來,同時顯示錯誤發生的調用棧資訊。這為解決問題提供了最直接的協助,當然缺點是必須能夠重現 EXEC_BAD_ACCESS錯誤。
圖形效能對使用者體驗有直接的影響,Instruments中的Core Animation工具用於測量物理機上的圖形效能,通過視圖的重新整理頻率大小來判斷應用的圖形效能。例如一個複雜的列表滾動時它的重新整理率應該努力趨近於 60fps才能讓使用者覺得夠流暢,從這個數字也可以算出run loop最長的回應時間應該是16毫秒。
Instruments可以在物理機上顯示出被混合的圖層Blended Layer(用紅色標註),Blended Layer是因為這些Layer是透明的(Transparent),系統在渲染這些view時需要將該view和下層view混合(Blend)後才能 計算出該像素點的實際顏色,如果這種blended layer很多,那麼在滾動列表時就甭想有流暢的效果。
[UIColor clearColor],要知道背景顏色為clear color那可是圖形效能的大敵,基本意味著blended layer是跑不了的了,為什嗎?自己思考一下:)
很多視圖Layer由於Shadow、Mask和Gradient等原因渲染很高,因此UIKit提供了API用於緩衝這些Layer:[layer setShouldRasterize:YES],系統會將這些Layer緩衝成Bitmap位元影像供渲染使用,如果失效時便丟棄這些Bitmap重新生 成。圖層Rasterization柵格化好處是對重新整理率影響較小,壞處是刪格化處理後的Bitmap緩衝需要佔用記憶體,而且當圖層需要縮放時,要對刪格 化後的Bitmap做額外計算。 使用這個選項後時,如果Rasterized的Layer失效,便會標註為紅色,如果有效標註為綠色。當測試的應用頻繁閃現出紅色標註圖層時,表明對圖層 做的Rasterization作用不大。
Misaligned Image表示要繪製的點無法直接映射到頻幕上的像素點,此時系統需要對相鄰的像素點做anti-aliasing反鋸齒計算,增加了圖形負擔,通常這種問題出在對某些View的Frame重新計算和設定時產生的。
(4) Color Offscreen-Rendered Yellow
大部分Offscreen-Rendering都是和視圖Layer的Shadow和Mask相關,下列情況會導致視圖的Offscreen- Rendering: 1. 使用Core Graphics (CG開頭的類)。 2. 使用drawRect()方法,即使為空白。 3. 將CALayer的屬性shouldRasterize設定為YES。 4. 使用了CALayer的setMasksToBounds(masks)和setShadow*(shadow)方法。 5. 在螢幕上直接顯示文字,包括Core Text。 6. 設定UIViewGroupOpacity。
Designing for iOS: Graphics & Performance對 offsreen以及圖形效能有個很棒的介紹,(5) Color Copied Images Copied Image選項可以標註應用繪製時被Core Animation複製的圖片,標註成藍綠色。雖然我在運行時遇到過,不過個人感覺對圖形效能影響不大。 (6) Color Immediately,Flash Updated Regions, Color OpenGL Fast Path Blue Color Immediately選項表示Instruments在做color-flush操作時取消10毫秒的延時。Flash Updated Regions選項用於用紅色示標示出在螢幕上使用GPU計算繪製的圖層。Color OpenGL Fast Path Blue選項用於用藍色標示出在螢幕上由OpenGL compositor繪製的內容。 這三個選項對圖形效能的分析意義較小,通常僅作為參考。
如果需要對app的檔案和網路I/O情況做分析,可以用到這三個Instruments工具System Usage、File Activity和Network。
工具File Activity只能在模擬器中運行,因此資料擷取可能不是非常準確。它同樣可以詳細給出讀取的檔案屬性、大小、載入時間等資訊,適合與System Usage配合使用。
涉及iOS App效能的知識很多,上面只是冰山一角,重點推薦WWDC的session。
- 406: Adopting Automatic Reference Counting
- 238: iOS App Performance: Graphics and Animations
- 242: iOS App Performance: Memory
- 235: iOS App Performance: Responsiveness
- 409: Learning Instruments
- 706: Networking Best Practices
- 514: OpenGL ES Tools and Techniques
- 506: Optimizing 2D Graphics and Animation Performance
- 601: Optimizing Web Content in UIWebViews and Websites on iOS
- 225: Up and Running: Making a Great Impression with Every Launch
- 105: Polishing Your App: Tips and tricks to improve the responsiveness and performance
- 121: Understanding UIKit Rendering
- 131 performance optimization on iphone os
- 308: Blocks and Grand Central Dispatch in Practice
- 323: Introducing Automatic Reference Counting
- 312: iOS Performance and Power Optimization with Instruments
http://oleb.net/blog/2011/11/ios5-tech-talk-michael-jurewitz-on-performance-measurement/
http://robots.thoughtbot.com/post/36591648724/designing-for-ios-graphics-performance
http://www.touchwonders.com/en/how-to-make-your-apps-feel-responsive-and-fast-part-2/
iOS App效能最佳化