淺談 iOS 中的檢視優化

kuailejim發表於2016-12-13

引言:
讓我們來思考幾個問題,你開發過的產品,它還有可以優化的地方嗎?能增加它的幀率嗎?能減少多餘的CPU計算嗎?是不是存在多餘的GPU渲染?業務這點工作量對於越來越強大的裝置面前顯得微不足道,但作為一個細心的開發者,我覺得很有必要來談談iOS中的檢視優化。

本文從開發者最容易犯錯的地方出發,結合例子,從以下幾個角度闡述如何進行檢視優化:

  • Color Blended Layers
  • Color Copied Images
  • Color Misaligned Images
  • Color Offscreen-Rendered

這個4個選項,可以從模擬器的Debug選項中看到

淺談 iOS 中的檢視優化

別急,我們一個個來看,首先是Color Blended Layers

Color Blended Layers

官方是這麼描述它的:

Shows blended view layers. Multiple view layers that are drawn on top of each other with blending enabled are highlighted in red. Reducing the amount of red in your app when this option is selected can dramatically improve your app’s performance. Blended view layers often cause slow table scrolling.

簡單來說,螢幕上的每個畫素點的顏色是由當前畫素點上的多層layer(如果存在)共同決定的,GPU會進行計算出混合顏色的RGB值,最終顯示在螢幕上。而這需要讓GPU計算,所以我們要儘量避免設定alpha,這樣GPU會忽略下面所有的layer,節約計算量。

下面讓我們來看一下設定alpha的效果,上面的灰色小塊是透明的。

淺談 iOS 中的檢視優化

淺談 iOS 中的檢視優化

效果很明顯,設定了透明的view會讓GPU計算圖層混合後的最終結果。

我想再提一下opaque這個屬性,網上普遍認為view.opaque = YES,GPU就不會進行圖層混合計算了。而這個結論是錯誤的,其實view.opaque事實上並沒什麼卵用。
如果你真的想達到這個效果,可以用layer.opaque,這個才是正確的做法

Color Copied Images

"If an image is in a color format that the GPU can not directly work with, it will be converted in the CPU."

Session 419 WWDC 2014中詳細介紹了這貨,其實這個東西跟開發者並沒什麼關係,遇到這種情況,我們大可以摔鍋給設計(當然你亂做優化導致圖片顏色格式改變,那就沒辦法了)。

簡而言之,蘋果的GPU只解析32bit的顏色格式,記住是32bit
如果你放一張圖片,而它的顏色格式卻不是32bit,CPU會先進行顏色格式轉換,再讓GPU渲染。乖乖的CPU就默默做了這個多餘的工作。

所以給你兩個選擇:

  • 讓設計溼都給你切32bit的圖
  • 自己去跑個非同步執行緒來轉換顏色去吧,不要去堵塞本來就壓力很大的主執行緒!

你選哪個?當然是讓設計溼切圖啦,我才不願意多寫程式碼。
而且於情於理,就算非同步轉換顏色,也會導致效能損耗,比如電量增多,發熱強變大等等等等

上demo:

淺談 iOS 中的檢視優化

淺談 iOS 中的檢視優化

兩個一樣的圖,僅僅是採用了不同顏色格式,上面是32bit,下面是8bit,於是乎,8bit的會導致Color Copied Images8,讓CPU多運算了。

Color Misaligned Images

Misaligned Image表示要繪製的點無法直接對映到頻幕上的畫素點,此時系統需要對相鄰的畫素點做anti-aliasing反鋸齒計算,增加了圖形負擔,通常這種問題出在對某些View的Frame重新計算和設定時產生的。

很簡單,不要出現image sizeimageView size不同的情況,這樣會觸發反鋸齒計算,增加效能損耗。

上demo:

淺談 iOS 中的檢視優化

一下就好看出來,下面的圖片尺寸不合適。

所以,實際開發中,本地的圖片比較好把控,只需要寫好對應的尺寸就好了,但是對於download下來的圖片,可以在載入完後進行size處理,以滿足imageView frame。特別是對於很多app,有大量的tableview,如果進行處理,則會大幅度提高流暢度。

Color Offscreen-Rendered

最後就是Offscreen-Rendered(離屏渲染)了。

這個東西講起來感覺非常複雜,我覺得只需要知道,離屏渲染會導致CPU在後臺儲存一份bitmap,所以會導致CPU多餘運算。

而避免的方式則是避免去做觸發的動作:

  • 重寫drawRect方法
  • masksToBounds
  • 其他一些手動觸發離屏渲染的動作

最後看個demo:

淺談 iOS 中的檢視優化

淺談 iOS 中的檢視優化

如圖所示,觸發了離屏渲染。

總結:

如果開發階段都注意到這些細節,那麼我覺得效能將不會是很大的問題了。

相關文章