http://www.lxweimin.com/p/d27323c18790
- 當在較短時間顯示大量圖片時(比如 TableView 存在非常多的圖片并且快速滑動時),CPU 占用率很低,GPU 占用非常高,界面仍然會掉幀。
避免這種情況的方法只能是盡量減少在短時間內大量圖片的顯示,盡可能將多張圖片合成為一張進行顯示。
- 當圖片過大,超過 GPU 的最大紋理尺寸時,圖片需要先由 CPU 進行預處理,這對 CPU 和 GPU 都會帶來額外的資源消耗。目前來說,iPhone 4S 以上機型,紋理尺寸上限都是 4096x4096,更詳細的資料可以看這里:iosres.com。
所以,盡量不要讓圖片和視圖的大小超過這個值(紋理尺寸上限)。
- 當多個視圖(或者說 CALayer)重疊在一起顯示時,GPU 會首先把他們混合到一起。如果視圖結構過于復雜,混合的過程也會消耗很多 GPU 資源。
為了減輕這種情況的 GPU 消耗,應用應當盡量減少視圖數量和層次,并在不透明的視圖里標明 opaque 屬性以避免無用的 Alpha 通道合成。當然,這也可以用上面的方法,把多個視圖預先渲染為一張圖片來顯示。
- CALayer 的 border、圓角、陰影、遮罩(mask),CASharpLayer 的矢量圖形顯示,通常會觸發離屏渲染(offscreen rendering),而離屏渲染通常發生在 GPU 中。當一個列表視圖中出現大量圓角的 CALayer,并且快速滑動時,可以觀察到 GPU 資源已經占滿,而 CPU 資源消耗很少。這時界面仍然能正常滑動,但平均幀數會降到很低。
為了避免這種情況,可以嘗試開啟 CALayer.shouldRasterize 屬性,但這會把原本離屏渲染的操作轉嫁到 CPU 上去。對于只需要圓角的某些場合,也可以用一張已經繪制好的圓角圖片覆蓋到原本視圖上面來模擬相同的視覺效果。
最好把需要顯示的圖形在后臺線程繪制為圖片,避免使用圓角、陰影、遮罩等屬性。