Android View渲染效能優化
Android View 渲染效能優化
好久沒寫文章了,應該至少兩年多了,這兩年工作轉換了很多,現在又重回 Android 開發的行列,最近工作上剛好遇到需要優化一個頁面的渲染性能(解決卡頓問題),所以剛好透過這篇文章來覆盤跟總結一下 Android 性能優化
造成 View 渲染緩慢的原因
在這個 Case 中,有幾個非常常見的 View 卡頓原因,這邊就列出這幾個常見的 Case
Layout 佈局過於複雜
因為 inflate 需要花費的時間過久,如果你的 Layout 層次過於複雜的話,所以需要盡量減少 Layout 佈局的複雜度,善用ConstraintLayout
去減少佈局的複雜度
RecycleView 頻繁全局刷新
這個蠻容易在開發過程中出現的一個錯誤,RecyclerView 主要的更新流程是透過
GetData –> setAdapter –> 通知 RecyclerView 更新
在通知 RecyclerView 更新這個環節有許多的方法
1 | final void notifyDataSetChanged() |
但是這邊常犯的錯誤是直接呼叫 notifyDataSetChanged
,這個會直接使整個 RecyclerView 全局刷新,但我們有時候獲得的資料只是一小部分的改動,所以我們應該根據當下情況去使用其他的 function,或者使用 Android 官方提供的DiffUtil
去幫助做資料更新的比對
ref : https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil
局部更新造成全局更新
這個在這個 case 上,很容易發生的是在動態改變 text 內容的 TextView 之上,假設今天有一個場景,是有一個倒數計時的 UI 呈現,那麼就會定時地去更新該 TextView,但是如果 TextView 的 width 跟 height 是wrap_content
,那就會造成這個 TextView 有機會的去更新全局的 UI。
onDraw, onMeasure, onLayout 時做了耗時操作
這幾個關鍵函數,都應該只做他們的自我權責,不應該在這些 Function 裡面做不必要的耗時操作,尤其是 onDraw,這也會造成 UI 渲染的效能瓶頸
頻繁 Add/Remove
頻繁 Add/Remove 也是會觸發整個佈局的重新繪製,所以應該避免
如何找出緩慢的貧頸
上述就是常見的幾種錯誤使用方式,但是我們在開發的時候,可能會遇到難以查找是什麼原因造成整體重繪(有可能上述狀況都有,不好定義),可以透過 Android 自帶的工具或者一些方式
在 RootView 的 requestLayout print stacktree
可以複寫 RootView 的 requestLayout function,並且在裡面打印 stacktree,這樣可以查找出是哪一個 UI 元件呼叫 stacktree,
透過開發者工具測量速度
在開發者選項裡有一個”硬件加速渲染“,裡面有一個“調試 GPU 過度繪製”,這個會在屏幕上以顏色來區分 overdraw(過度繪製,也就是進行了不必要的繪製)的嚴重重度:
- 藍色 1 倍 overdraw
- 綠色 2 倍 overdraw
- 紅色 3 倍 overdraw
- 紫色 4 倍 overdraw
在開發者選項面有一個是監控
選擇GPU使用情況
,選擇第二個在螢幕上顯示條型
,就可以在手機上即時觀測到目前的使用情況
參考文件 :