背景
最近在做APP性能專項測試脖阵,視頻剪輯過程中出現多次卡頓掉幀的問題力穗,為了更好地了解出現掉幀卡頓的原因转砖,去查閱了資料并記錄下該文章
過程
視圖渲染過程
了解卡頓原因之前蔫仙,先了解下視圖渲染過程如下圖:
1、CPU計算顯示的內容(如文本繪制巨坊,UI布局計算撬槽,視圖創(chuàng)建,圖片解碼等等)趾撵,然后把計算好的內容提交給GPU
2侄柔、GPU 渲染(變換,圖層合成占调,紋理渲染等)完成后暂题,將渲染結果放入幀緩沖區(qū)
3、視頻控制器會按照 VSync 信號逐行讀取幀緩沖區(qū)的數據究珊,經過可能的數模轉換傳遞給顯示器顯示
備注:
1薪者、顯示器上的所有圖像都是一線一線的掃描上去的(從左到右,從上到下刷新)剿涮,如下圖:
2言津、 V-SYNC:即垂直同步信號量攻人,這里的V即垂直的意思;當整個屏幕刷新完畢悬槽,即一個垂直刷新周期完成贝椿,顯示器會發(fā)出 VSync 信號
3、水平同步可能會出現畫面撕裂的現象(如下圖)陷谱。因為畫面的渲染不是整個畫面一起渲染的烙博,是逐行逐列渲染。如果沒有開啟垂直同步烟逊,設備配置不夠渣窜,則畫面在高速移動中會出現一行還沒刷新完成就出現下一行,進而出現撕裂情況
4宪躯、垂直同步就是為了解決畫面撕裂的問題乔宿,當開啟垂直同步后,GPU 會等待顯示器的 VSync 信號發(fā)出后访雪,才進行新的一幀渲染和緩沖區(qū)更新详瑞。這樣能解決畫面撕裂現象,也增加了畫面流暢度臣缀,但需要消費更多的計算資源坝橡,也會帶來部分延遲。
5精置、目前计寇,iOS設備使用雙緩存,并開啟垂直同步脂倦,Android是三緩存番宁,并開啟垂直同步(緩存之間怎么切換的呢?赖阻?蝶押?)
UI 卡頓和掉幀的原因
首先,先了解下基礎的知識:假定設備的刷新率是60HZ火欧,如果頁面的滑動流暢率為60fps棋电,也就是一秒更新60張圖片,人眼上看就是流暢的效果布隔,也就是每隔16.7ms(1/60)就要產生一幀的畫面离陶,即:每隔16.7ms發(fā)出V-SYNC信號,觸發(fā)對UI進行渲染衅檀,這一幀的畫面需要由CPU和GPU共同協同完成顯示(詳見上面的視圖渲染過程)
卡頓掉幀原因:
如果在一個 VSync 時間內,CPU花費的時間比較長霎俩,留給GPU的時間就比較少哀军,GPU+CPU總時間就可能超過16.7ms沉眶,下一幀到來前,沒準備好當下幀的畫面杉适,這時候顯示器還是顯示上一幀的畫面谎倔,就出現掉幀,就出現滑動卡頓猿推;
同理片习,如果GPU花費的時間比較長,總時長也可能超過16.7ms
所以蹬叭,CPU 和 GPU 不論哪個阻礙了顯示流程藕咏,都會造成掉幀現象
滑動流暢性方案
經過上面的分析秽五,為了優(yōu)化掉幀卡頓問題孽查,我們就需要對CPU和GPU的處理過程進行優(yōu)化
減輕CPU壓力
- 對象創(chuàng)建,調整坦喘,銷毀放在子線程中做
- 預排版(布局計算盲再,文本計算)放在子線程,主線程有更多時間響應用戶交互
- 預渲染(文本異步繪制瓣铣、圖片編解碼答朋,圖像繪制)放在子線程
減輕GPU壓力
- 紋理渲染,觸發(fā)離屏渲染棠笑,避免離屏渲染绿映,依托cpu異步繪制機制減輕CPU壓力
- 視圖混合:多個視圖層層疊加,合成需要大量計算腐晾,減輕視圖層級的復雜性叉弦,減輕GPU的壓力,
參考文檔:https://blog.csdn.net/smnisbear/article/details/51170932
Perfdog中的性能指數
先講下以下的幾個參數:
FPS
Frames Per Second藻糖;應用界面平均每秒刷新次數淹冰,
- Avg(FPS):平均幀率(一段時間內平均FPS)
- Var(FPS):幀率方差(一段時間內FPS方差),體現幀率的穩(wěn)定性
- Drop(FPS):降幀次數(平均每小時相鄰兩個FPS點下降大于8幀的次數)
備注:幀率低巨柒,并不一定是卡頓樱拴,如果渲染不是均勻的,即使幀率高洋满,也可能會出現一卡一卡的現象
Jank和BigJank
Jank:1s內卡頓次數
BigJank:1s內嚴重卡頓次數
PerfDog Jank計算方法:
1. 同時滿足以下兩條件晶乔,則認為是一次卡頓Jank.
a) 當前幀耗時>前三幀平均耗時2倍。
b) 當前幀耗時>兩幀電影幀耗時(1000ms/242=84ms)牺勾。
2. 同時滿足兩條件正罢,則認為是一次嚴重卡頓BigJank.
a) 當前幀耗時>前三幀平均耗時2倍。
b) 當前幀耗時>三幀電影幀耗時(1000ms/243=125ms)驻民。
stutter
測試過程中翻具,卡頓時長的占比履怯。即Stutter(卡頓率)=卡頓時長/總時長
卡頓時長計算:基于Jank的基礎上,一次Jank卡頓裆泳,會有一次卡頓時間Jank time叹洲。測試過程中可能有多次Jank卡頓,即有多次卡頓時間Jank time工禾≡颂幔卡頓時長即為多次卡頓時間的和
FrameTime
上下幀畫面顯示時間間隔,也可簡單認為單幀渲染耗時
Avg(FTime):平均幀耗時
測試注意事項
1闻葵、流暢度不等于FPS民泵,需要多維度衡量,考慮FPS笙隙,Jank洪灯,Stutter
2、APP需要關注FPS竟痰、Jank及卡頓率签钩。只是需要區(qū)分使用場景,如:
(1)坏快、靜態(tài)頁面窗口
只需關注FPS铅檩,理論FPS應該為0,否則莽鸿,說明有冗余刷新昧旨,容易引起手機發(fā)熱及耗電。
(2) 有滾動動畫頁面窗口
只需關注FPS祥得,FPS處于合適值即可兔沃,無需高頻刷新。
(3)快速滑動頁面窗口级及。
需要關注FPS乒疏、Jank及卡頓率。手機交互靈敏度就是來源于此饮焦,一般滑動狀態(tài)下怕吴,幀率越高越好,Jank越小越好县踢。
(4) 播放視頻頁面窗口转绷。
需要關注FPS、Jank及卡頓率硼啤,視頻卡頓直接影響用戶议经。視頻一般幀率18-24幀,Jank=0。比如微信播放視頻爸业、視頻播放器等其骄。