iOS如何提高頁面流暢度

滴水微瀾發表於2017-10-13

A.提高CPU效能

物件建立
1.儘量用輕量的物件代替重量的物件,比如CALayer 比 UIView 要輕量許多,如果不考慮互動事件的話,可以選擇CALayer。
2.Storyboard和xib載入物件時,消耗的成本比程式碼多。在使用時需要綜合考慮。
3.使用物件的預載入和懶載入,減少使用時載入的負擔。

物件調整
1.UIView 的關於顯示相關的屬性(比如 frame/bounds/transform)等實際上都是 CALayer 屬性對映來的,所以對 UIView 的這些屬性進行調整時,消耗的資源要遠大於一般的屬性。不用頻繁修改。
2.UIView和CALayer層次的修改會激發很多代理和通知,儘量少去調整層次。

物件的消耗
1.物件容器型物件的消耗需要重視,儘量放到後臺進行銷燬。
Tip:
NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
[tmp class];
});

佈局計算
1.app內檢視計算通常比較銷燬CPU效能,而且算出的結果通常是修改uiview的frame相關屬性,更是消耗cpu效能,所以儘量避免頻繁的佈局更新

Autolayout
1.自動佈局對cpu的消耗隨著複雜度是呈指數級的,故慎用

文字計算
1.頁面的文字計算一般是無法避免的,自己手動計算可以提高效能

文字渲染
1.常見的文字控制元件 (UILabel、UITextView 等),其排版和繪製都是在主執行緒進行的,當顯示大量文字時,CPU 的壓力會非常大。
對此解決方案只有一個,那就是自定義文字控制元件,用 TextKit 或最底層的 CoreText 對文字非同步繪製。

圖片解碼
當用 UIImage 或 CGImageSource 的那幾個方法建立圖片時,生成的物件不會立即解碼,而是當圖片設定到 UIImageView 或者 CALayer.contents 中去,並且 CALayer 被提交到 GPU 前,CGImage 中的資料才會得到解碼。解碼都是在主執行緒中,影響效能。
常見的做法是在後臺執行緒先把圖片繪製到 CGBitmapContext 中,然後從 Bitmap 直接建立圖片。目前常見的網路圖片庫都自帶這個功能。

影象繪製
1.影象的繪製通常是指用那些以 CG 開頭的方法把影象繪製到畫布中,然後從畫布建立圖片並顯示這樣一個過程。這個最常見的地方就是 [UIView drawRect:] 裡面了。由於 CoreGraphic 方法通常都是執行緒安全的,所以影象的繪製可以很容易的放到後臺執行緒進行。一個簡單非同步繪製的過程大致如下(實際情況會比這個複雜得多,但原理基本一致):
- (void)display {
dispatch_async(backgroundQueue, ^{
CGContextRef ctx = CGBitmapContextCreate(...);
// draw in context...
CGImageRef img = CGBitmapContextCreateImage(ctx);
CFRelease(ctx);
dispatch_async(mainQueue, ^{
layer.contents = img;
});
});
}

B.提高GPU效能
紋理渲染
1.當在較短時間顯示大量圖片時(比如 TableView 存在非常多的圖片並且快速滑動時),CPU 佔用率很低,GPU 佔用非常高。避免這種情況的方法只能是儘量減少在短時間內大量圖片的顯示,儘可能將多張圖片合成為一張進行顯示。
2.當圖片過大,超過 GPU 的最大紋理尺寸時,圖片需要先由 CPU 進行預處理,這對 CPU 和 GPU 都會帶來額外的資源消耗。目前來說,iPhone 4S 以上機型,紋理尺寸上限都是 4096×4096。所以,儘量不要讓圖片和檢視的大小超過這個值。

檢視混合
1.當多個檢視或者CALayer混合顯示時,GPU會將它們混合到一起,如果檢視多,結構複雜就會增加混合難度。解決方法:減少檢視個數和層次,在不透明的檢視中標明opaque 屬性以避免無用的 Alpha 通道合成。或者把它們合成到一張大圖上。

圖形生成
1.CALayer 的 border、圓角、陰影、遮罩(mask),CASharpLayer 的向量圖形顯示,通常會觸發離屏渲染(offscreen rendering),而離屏渲染通常發生在 GPU 中。當一個列表檢視中出現大量圓角的 CALayer,並且快速滑動時,可以觀察到 GPU 資源已經佔滿,而 CPU 資源消耗很少。
為了避免這種情況,可以嘗試開啟 CALayer.shouldRasterize 屬性,但這會把原本離屏渲染的操作轉嫁到 CPU 上去。另外解決方法是把需要顯示的圖形在後臺執行緒繪製為圖片,避免使用圓角、陰影、遮罩等屬性。


非同步渲染框架
AsyncDisplayKit,提高頁面的流暢度

 

 

參考文章:iOS 保持介面流暢的技巧 https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/

相關文章