UIKit性能調(diào)優(yōu)實(shí)戰(zhàn)講解

總結(jié)

避免圖層混合
  • 確保控件的opaque屬性設(shè)置為true,確保backgroundColor和父視圖顏色一致且不透明
  • 如無(wú)特殊需要,不要設(shè)置低于1的alpha值
  • 確保UIImage沒(méi)有alpha通道
避免臨時(shí)轉(zhuǎn)換
  • 確保圖片大小和frame一致,不要在滑動(dòng)時(shí)縮放圖片
  • 確保圖片顏色格式被GPU支持,避免勞煩CPU轉(zhuǎn)換
慎用離屏渲染
  • 絕大多數(shù)時(shí)候離屏渲染會(huì)影響性能
  • 重寫(xiě)drawRect方法,設(shè)置圓角、陰影、模糊效果,光柵化都會(huì)導(dǎo)致離屏渲染
  • 設(shè)置陰影效果是加上陰影路徑
  • 滑動(dòng)時(shí)若需要圓角效果,開(kāi)啟光柵化
  • 為什么要把控件盡量設(shè)置成不透明的,如果是透明的會(huì)有什么影響,如何檢測(cè)這種影響?

注解:
很多文章里說(shuō)把控件設(shè)置為opaque = true,其原理就是希望避免圖層混合,然而這種調(diào)優(yōu)一般情況下用處不大。因?yàn)閁IView的opaque屬性默認(rèn)值就是true,也就是說(shuō)只要不是人為設(shè)置成透明,都不會(huì)出現(xiàn)圖層混合。

個(gè)人認(rèn)為比opaque屬性更重要的是backgroundColor屬性,如果不設(shè)置這個(gè)屬性,控件依然被認(rèn)為是透明的,所以我們做的第一個(gè)優(yōu)化是在CustomTableCell類(lèi)的init方法中添加一行代碼:

label.backgroundColor = UIColor.whiteColor()
  • 為什么cell中的圖片,盡可能要使用正確的大小、格式,如果錯(cuò)誤會(huì)有什么影響,如何檢測(cè)這種影響?
  • 為什么設(shè)置陰影和圓角有可能影響滑動(dòng)時(shí)流暢度?
  • shouldRasterize和離屏渲染的關(guān)系是什么,何時(shí)應(yīng)該使用?
光柵化

光柵化是將一個(gè)layer預(yù)先渲染成位圖(bitmap),然后加入緩存中。如果對(duì)于陰影效果這樣比較消耗資源的靜態(tài)內(nèi)容進(jìn)行緩存,可以得到一定幅度的性能提升。demo中的這一行代碼表示將label的layer光柵化:

label.layer.shouldRasterize = true 
顏色格式
圖片大小

在demo中,每個(gè)UIImageView的大小都是180x180,而只有第二張圖片的像素大小是360x360。因此除了第二張圖片,其他的圖片都需要被縮放。

圖片的縮放需要占用時(shí)間,因此我們要盡可能保證無(wú)論是本地圖片還是從網(wǎng)絡(luò)或取得圖片的大小,都與其frame保持一致
第三個(gè)優(yōu)化是調(diào)整所有圖片的像素大小以避免不必要的縮放。
離屏渲染

離屏渲染可能會(huì)自動(dòng)觸發(fā),也可以手動(dòng)觸發(fā)。以下情況可能會(huì)導(dǎo)致觸發(fā)離屏渲染:

  • 重寫(xiě)drawRect方法
  • 有mask或者是陰影(layer.masksToBounds, layer.shadow*),模糊效果也是一種mask
  • layer.shouldRasterize = true

前兩者會(huì)自動(dòng)觸發(fā)離屏渲染,第三種方法是手動(dòng)開(kāi)啟離屏渲染。

使用了陰影,接下來(lái)我們進(jìn)行第四個(gè)優(yōu)化,在設(shè)置陰影效果的四行代碼下面添加一行:

imgView.layer.shadowPath = UIBezierPath(rect:imgView.bounds).CGPath 

這行代碼制定了陰影路徑,如果沒(méi)有手動(dòng)指定,Core Animation會(huì)去自動(dòng)計(jì)算,這就會(huì)觸發(fā)離屏渲染。
如果人為指定了陰影路徑,就可以免去計(jì)算,從而避免產(chǎn)生離屏渲染。

設(shè)置cornerRadius本身并不會(huì)導(dǎo)致離屏渲染,但很多時(shí)候它還需要配合layer.masksToBounds = true使用。

根據(jù)之前的總結(jié),設(shè)置masksToBounds會(huì)導(dǎo)致離屏渲染

解決方案是盡可能在滑動(dòng)時(shí)避免設(shè)置圓角,如果必須設(shè)置圓角,可以使用光柵化技術(shù)將圓角緩存起來(lái):

// 設(shè)置圓角
label.layer.masksToBounds = true 
label.layer.cornerRadius = 8 
label.layer.shouldRasterize = true 
label.layer.rasterizationScale = layer.contentsScale 

轉(zhuǎn)載:https://bestswifter.com/uikitxing-neng-diao-you-shi-zhan-jiang-jie/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容