一、成像原理
成像是CPU、GPU、顯示器是協(xié)同完成的。CPU 計算好顯示內(nèi)容提交到 GPU,GPU 渲染完成后將渲染結(jié)果放入幀緩沖區(qū),隨后視頻控制器會按照 VSync 信號逐行讀取幀緩沖區(qū)的數(shù)據(jù),然后顯示在屏幕上。

image.png
二、卡頓產(chǎn)生原因
在 VSync 信號到來后,系統(tǒng)圖形服務(wù)會通過 CADisplayLink 等機制通知 App,App 主線程開始在 CPU 中計算顯示內(nèi)容,比如視圖的創(chuàng)建、布局計算、圖片解碼、文本繪制等。隨后 CPU 會將計算好的內(nèi)容提交到 GPU 去,由 GPU 進行變換、合成、渲染。隨后 GPU 會把渲染結(jié)果提交到幀緩沖區(qū)去,等待下一次 VSync 信號到來時顯示到屏幕上。由于垂直同步的機制,如果在一個 VSync 時間內(nèi),CPU 或者 GPU 沒有完成內(nèi)容提交,則那一幀就會被丟棄,等待下一次機會再顯示,而這時顯示屏?xí)A糁暗膬?nèi)容不變。這就是界面卡頓的原因。

image.png
從上面的圖中可以看到,CPU 和 GPU 不論哪個阻礙了顯示流程,都會造成掉幀現(xiàn)象。所以開發(fā)時,也需要分別對 CPU 和 GPU 壓力進行評估和優(yōu)化。
三、檢測
1、平時所說的“卡頓”主要是因為在主線程執(zhí)行了比較耗時的操作
2、可以添加Observer到主線程RunLoop中,通過監(jiān)聽RunLoop狀態(tài)切換的耗時,以達到監(jiān)控卡頓的目的
四、優(yōu)化
- CPU 優(yōu)化
1、盡量提前計算好布局,在有需要時一次性調(diào)整對應(yīng)的屬性,不要多次修改屬性
2、Autolayout會比直接設(shè)置frame消耗更多的CPU資源
3、圖片的size最好剛好跟UIImageView的size保持一致
4、控制一下線程的最大并發(fā)數(shù)量
5、盡量把耗時的操作放到子線程
6、文本處理(尺寸計算、繪制)
7、圖片處理(解碼、繪制) - GPU 優(yōu)化
1、盡量避免短時間內(nèi)大量圖片的顯示,盡可能將多張圖片合成一張進行顯示
2、GPU能處理的最大紋理尺寸是4096x4096,一旦超過這個尺寸,就會占用CPU資源進行處理,所以紋理盡量不要超過這個尺寸
3、盡量減少視圖數(shù)量和層次
4、減少透明的視圖(alpha<1),不透明的就設(shè)置opaque為YES
5、盡量避免出現(xiàn)離屏渲染 - 離屏渲染(以下操作會觸發(fā)離屏渲染)
1、光柵化 ,layer.shouldRasterize = YES
2、遮罩,layer.mask
3、圓角,同時設(shè)置layer.masksToBounds = YES、layer.cornerRadius大于0??紤]通過CoreGraphics繪制裁剪圓角,或者叫美工提供圓角圖片
4、陰影,layer.shadowXXX 。如果設(shè)置了layer.shadowPath就不會產(chǎn)生離屏渲染