TableView效能優化

weixin_34234823發表於2018-08-31

TableView效能優化是一個老生常談的問題了,最近也正在做TableView的效能優化,在此我也做一個總結:

1.UITableViewCell重用機制?

UITableView只會建立一螢幕(或者一螢幕多一點)的cell,其他都是取出來重用的。每當cell滑出螢幕的時候,就會放到一個集合中,當要顯示某一位置的cell時,會先去集合中取,有的話,就直接拿出來顯示,沒有在建立。

2.tableView滑動為什麼會卡頓?

cell賦值內容時,會根據內容設定佈局,也就可以知道cell的高度,若有1000行,就會呼叫1000次 cellForRow方法,而我們對cell的處理操作,都是在這個方法中賦值,佈局等等,開銷很大。

3.優化方法

3.1優化:heightForRow方法處理cell高度。

     思路:賦值和計算佈局分離。cellForRow負責賦值,heightRorRow負責計算高度。

3.2自定義cell繪製:

    各個資訊都是根據之前算好的佈局進行繪製的。需要非同步繪製。重寫draeRect方法就不需要非同步繪製了,因為drawRect本來就是非同步繪製的。圖文混排的繪製,coreText繪製。

3.3按需載入(UIScrollView方面):

     如果目標行與當前行相差超過指定行數,只在目標滾動範圍的前後制定n行載入。滾動很快時,只載入目標範圍內得cell,這樣按需載入,極大地提高了流暢性。

4.總結所有的優化方法:

一般的優化方法:

1.提前計算並快取好高度,因為heightForRow最頻繁的呼叫。

2.cellForRow方法裡儘量減少計算量和程式碼量。

3.滑動時按需載入,這個在大量圖片展示,網路載入時,很管用。(SDWebImage已經實現非同步載入)。

4.重用cells。

5.如果cell內顯示得內容來自web,使用非同步載入,快取結果請求。

6.少用或不用透明圖層,使用不透明檢視,少使用圓角、陰影等。

7.用程式碼代替xib檔案,用手動設定frame方式代替自動佈局。(xib和自動佈局比較耗時)

8.cell檔案裡邊能提前算好的儘量快取起來,避免多次計算。

9.少用addView給cell動態新增view,可以初始化的時候就新增,然後通過hide控制是否顯示。

當上邊這些基本的優化都做過之後,發現自己的tableView還是有些卡頓,那你就需要考慮下邊的這些高階優化方案了。

高階的優化方法:

1.非同步繪製,遇到複雜介面,效能瓶頸時,可能是突破口。

2.模仿或者使用YYKit的設計思想,從底層影像繪製原理層面,去進行介面的繪製和佈局。

3.圖片解碼。解碼的原理也很簡單,提前把圖片繪製到一個CGContext中,再從Context獲取圖片,這樣能夠強制圖片解碼。通常三方庫(KingFisher,SDWebImage)都自帶後臺解碼。

4.預載入cell。提前建立cell並且快取到記憶體中,這時候要做好記憶體管理,不要讓記憶體太大導致APP崩潰。

5.從影像渲染、CPU和GPU處理影像操作方面做優化。

引用其他博主的總結:

1.效能分析就是一句話:能放到後臺的就放到後臺,不能放到後臺的要麼預載入,要麼拆分。另外還有一個Facebook出品的三方庫非常推薦:Texture,這個是一個非同步顯示框架,會省去很多事。

介面頓卡的原因

介面頓卡主要從兩個角度考慮

CPU限制:

物件的建立,釋放,屬性調整。這裡尤其要提一下屬性調整,CALayer的屬性調整的時候是會建立隱式動畫的,是比較損耗效能的。

檢視和文字的佈局計算,AutoLayout的佈局計算都是在主執行緒上的,所以佔用CPU時間也很多 。U

文字渲染,諸如UILabel和UITextview都是在主執行緒渲染的

圖片的解碼,這裡要提到的是,通常UIImage只有在交給GPU之前的一瞬間,CPU才會對其解碼。

GPU限制:

檢視的混合。比如一個介面十幾層的檢視疊加到一起,GPU不得不計算每個畫素點藥顯示的畫素

離屏渲染。檢視的Mask,圓角,陰影。

半透明,GPU不得不進行數學計算,如果是不透明的,CPU只需要取上層的就可以了

浮點數畫素

介面頓卡的優化

建議使用成熟的”輪子”,因為作為一個開發者,你的工作是寫出高質量的App,那麼為什麼不用那些已經驗證成功的框架呢?如果真的輪子不能實現,或者你有閒下來的時間,再造輪子未嘗不可。

使用AsyncDisplayKit

使用FaceBook出品的AsyncDisplayKit來寫複雜的介面。能夠獲得非同步繪製,預先載入等諸多好處。不過,需要一定的學習成本,前段時間看了下網易新聞的安裝包,就使用了AsyncDisplayKit

圖文混排引擎

大多數效能要求較高的介面就是圖文混排,比如微博Feed,微信朋友圈等介面。建議使用成熟的圖文混排引擎,因為這些引擎一般支援非同步繪製,並且做了大量優化。推薦兩個

YYKit

DTCoreText

非同步繪製

把複雜的介面,放到後臺執行緒裡繪製成一個bitmap,然後再顯示。雖然有些延遲,不過換來的卻是平滑的介面。

圖片的解碼

建議使用成熟的庫,比如SDWebImage等,能夠在後臺進行圖片解碼,減少CPU的使用。

預載入與快取

對於複雜的TableView,可以對Cell檢視的各個控制元件的大小,位置後臺進行預計算,並且快取起來。這樣保證在heightForRow和cellForRow中不進行大量的計算。

儘量使用CALayer

因為Layer是一個輕量級的檢視結構,它不接受通知,不接受觸控,不在響應鏈。所以,相對於UIView來說,它的效能較好。並且CALayer及其子類是可以使用GPU渲染的,能夠硬體加速。

圖層預合成

將兩個CALayer的內容合成到一個Bitmap裡,然後顯示。能夠減輕GPU的壓力


轉:https://blog.csdn.net/u013602835/article/details/79413649

相關文章