1.為什么出現頁面卡頓?
在開發中我們常常會遇到布局比較復雜的cell,在滑動的時候會導致界面不流暢,出現卡頓的現象,這是由于CPU計算和GPU渲染,之間未及時交換數據丟失幀導致的結果。
2.常見解決辦法
1).UIImageView盡量設置為不透明
opque盡量設置為YES
當UIImageView的opque設置為YES的時候其alpha的屬性就會無效,UIImageView的半透明取決于其圖片半透明或者UIImageView本身的背景色合成的圖層view是半透明的。
如果圖片全部不是半透明就不會觸發圖層的blend操作,整個圖層就會不透明。
如果疊加的圖片有出現半透明的,就會立馬觸發圖層的blend操作,整個圖層不透明。
背景色盡可能設為alpha值為1
當某一塊圖層的alpha和其superView的背景色alpha不一樣的時候會觸發alpha合成操作,這是一項看似很簡單但卻是非常消耗CPU性能的操作。
2).UIView的背景色設置
UIView的背景色盡量不要設置為clearColor,這樣也會觸發alpha疊加,在UITableView滑動的時候是非常消耗性能的。子視圖的背景色盡可能設置成其superView的背景色,這樣圖層合成的時候不會觸發blend操作。
最好不使用帶alpha通道的圖片,如果有alpha盡量讓UI設計人員取消alpha通道。
3).cell上layer盡量避免使用圓角
在工作中關于滑動界面我們會時常遇到cell行設置頭像為圓角等需求,這時候我們盡量避免使用layder.cornerRadius,因為這會觸發離屏渲染。離屏渲染很耗時間。
離屏渲染:是GPU渲染區的一個渲染緩沖區,我們所用的所有顯示屏的圖形圖像都是通過GPU進行渲染,然后顯示在屏幕上。GPU負責渲染會把渲染的圖形放到緩沖區然后CPU就會發一個垂直信號顯示到屏幕。
如果要使用圓角,我們可以設置為layer.shouldRasterize = YES,其實這個設置是觸發光柵化,可以大大提高渲染的性能。我的理解光柵化就是類似于cell的重用機制。
光柵化:把第一次渲染好的圖層放到緩沖區,那么下次不需要再離屏渲染直接就可以從緩沖區拿去使用。
4).優化圖片的加載方式
圖片的加載方式有兩種形式:
UIImageView *image = [UIImageView imageView:@"1.png"];
UIImageView *image = [UIImageView imageWithContentOfFile:@"1.png"];
兩種加載圖片方式的區別:
第一種:當我們經常需要這張圖片并且僅僅是小圖的時候,我們可以使用此種方式加載圖片。
這種方式是把圖片緩存在圖片緩存區,當我們使用的時候會通過圖片的名字也就是通過key的方式去查找圖片在緩存區的內存地址。
當我們使用很多圖片的時候系統就會開辟很多內存來存儲圖片,所以qq、微信我們很多時候都會去清除緩存操作。
第二種:當我們使用工程里面的一張大圖并且使用次數很少甚至為1次的時候,我們優先會采用這種方式加載圖片,這種方式當使用完圖片的時候會立即丟棄釋放資源,所以對性能不會帶來負擔。
5).盡量延遲圖片的加載
當我們在滑動頁面的時候尤其對于那種布局特別復雜的cell,滑動的時候不要加載圖片,當滑動停止得時候再進行圖片的加載。
我們都知道不管是UITableView還是UIScrollView在滾動的時候需要顯示東西都是通過runLoop去拿。
當滾動的時候runLoop會處于NSRunLoopTrackingMode的模式,我們可以通過一個主線程隊列dispatch_after或者selfPerformSelector設置runLoop的模式為NSDefaultRunLoopMode模式,就可以做到停止滾動再加載圖片。
注:其實嚴格意義上selfPerformSelector的事件就是在主線程隊列中等待。
優先加載理念
采用優先加載的理念,既先展示一部分,當滑動的時候再加載下面的一部分這樣就保持流暢。
6).避免阻塞主線程
讓圖片的繪制、圖片的下載、對象的創建、文本的渲染等這些耗時的操作盡可能采用子線程異步的方式去處理,對于layer及UI的操作不得不在主線程里面,只能想辦法優化。
7).xib、storyBoard、純代碼的問題
蘋果推出storyboard確實為開發者節省了大量的時間,提高了開發效率,但是對于那種
復雜的滑動界面,利用storyboard是非常消耗資源的,不信的可以試試用性能工具timeProfie看看CPU所占的性能百分比,其CPU的資源遠遠大于純代碼布局。