你們都知道CPU(中央處理器)主要負責數學和邏輯運算,在很早前,CPU還負責圖像的顯示操做,可是這樣會大大的下降CPU的運算性能,因此GPU應運而生,GPU主要負責圖像的渲染與顯示,至此,CPU只須要給GPU發出指令,GPU再將咱們寫好的頁面柵格化渲染顯示出來,以一個button爲例!api
<Button>屬性設置【Width = 「100dp」;Height = 「100dp」】-->經過LayoutInflater將xml映射成對象加載到內存-->檢測<Button>包含的屬性信息-->CPU通過計算-->將<Button>處理爲多維向量圖形→CPU將圖形交給GPU→GPU進行圖形繪製(柵格化:將圖片等矢量資源,轉化爲一格格像素點的像素圖,顯示到屏幕上)(哪一個位置是什麼顏色的像素點,最終將圖形鋪滿。注:手機屏幕由無數個像素點堆積而成)。app
總結來講就是CPU將UI對象計算成成多維圖形(多邊形、紋理),再經過OPENGL進行處理,處理完以後再交給GPU進行柵格化渲染並交給顯示器進行顯示。工具
因爲人眼的特殊構造,對於60fps如下的幀率畫面,會給人一種卡頓的現象,因此就出現了16ms原則(1000ms/60fps = 16ms),即要保證頁面16ms刷新一次。佈局
Android系統每隔16ms發出vsync信號,觸發對UI進行渲染,1s內大約刷新屏幕60次,顯示60幀的數據。性能
fps:畫面每秒鐘傳輸的幀率,幀率越高,畫面越流程,反之越卡頓優化
上面咱們講到了16ms原則,那麼16ms原則對咱們的UI產生了什麼樣的影響呢?url
由於16ms原則,咱們顯示器將頁面顯示出來分兩種狀況:spa
1.上述步驟在16ms內完成,true→顯示器直接顯示。.net
2.上述步驟在16ms內沒有完成(可能因爲CPU計算的時間過長或者因爲GPU的渲染時間過長,最終致使整個流程下來超過了16ms),false-->垂直同步等待下一幀完成。調試
解釋一下垂直同步機制:好比說第一幀在16ms內渲染完成,而且顯示出來了,第二幀在上述的處理流程中超過了16ms,在16ms內沒有完成,那麼,屏幕就不會顯示第二幀的數據,依舊只顯示第一幀的數據,接下來處理第三幀,第三幀的數據在16ms內處理完了上述的流程,那麼結果就是屏幕會將第二幀的數據和第三幀的數據一塊兒顯示出來(若是在某一處出現了丟幀的狀況,大機率會影響到後面的繪製也會出現丟幀的狀況),若是計算器cpu的計算能力和gpu的渲染能力不好,就會出現咱們說的UI卡頓的現象。(用LOL舉一個例子,好比咱們1-10幀都沒有在16ms內完成(打團中,UI過於複雜),第11幀在16ms內完成(打完團,回家泡泉水),這時候就會把1-11幀的數據都顯示出來,這時候給人的感受就是花裏胡哨的閃現出一堆技能)
看了上面的解釋,是否是有一種明朗的感受了,總的來講就是幀率太低,垂直同步機制的限制下,咱們前面幾幀的畫面渲染不出來,直到某一幀咱們的幀率正常了,這時候就會把前面的幾幀一塊兒渲染出來,這樣就形成了咱們所說的視覺上卡頓的現象了。
既然咱們知道了形成卡頓的緣由了,那麼,咱們應該去如何檢測和避免呢?這裏就要介紹一下過分繪製了!
前面咱們說到了手機屏幕是由無數個像素點堆積而成的,一個像素點被咱們重複屢次的渲染,就是過分繪製
開發者選項-->調試gpu過分繪製-->顯示過分繪製區域
1)避免UI層級嵌套的過深
2)減小沒必要要的背景設置(根節點背景是否能夠不要、系統主題背景是否能夠不要等等)
3)使用merge標籤減小布局嵌套層次
4)使用ConstraintLayout替代常見嵌套佈局,減小布局層次
5)在自定義view的時候,使用Canvas的clipRect和clipPath方法限制View的繪製區域(覆蓋區域不須要繪製)