2020年3月15日 星期日

[Android] RecyclerView 頻繁刷新效能最佳化

markdown 有頻繁刷新 RecyclerView 的需求時,有時候會產生一些性能問題,那 RecyclerView 最佳化的方向有幾個,大概整理如下,供以後需要時備查。 ### DiffUtil [DiffUtil](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/DiffUtil) 是 Google 開發出來跟 RecyclerView 搭配使用的一個工具類,用途是計算出新舊 list item 中有差異的項目,以求最小化更新 list 節省 CPU 時間。 使用方法非常簡單,只需要實做 [DiffUtil.Callback](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/DiffUtil.Callback) 介面,剩下找出 list 差異項目的工作就交給 DiffUtil 實現,套用這個最佳化方法 effort 很小。 但是要注意的是,若是 list 很大而且內部資料幾乎每次全部都會變動的話則不適合使用 DiffUtil,反而會造成耗時增加,還是要看一下實際場景,再決定要不要使用。 ### StaticLayout 若是 list 中有 TextView 的話,可以看一下是不是花了很多時間在 setText method 上,因為在套用 DynamicLayout 的時候 setText 是很耗時的,此時可以參考 Instagram 的最佳化 TextView 文章,使用 StaticLayout 來節省 CPU 時間。 這個最佳化方法比較複雜,所以在決定套用前,要先確定 setText 是不是效能瓶頸,TextView 也有可能自己就選擇使用 BoringLayout 或 StaticLayout,要看實際場景以及 TextView 內部演算法決定。 ### View Pool RecyclerView 預設 View Pool 的數量是 5,也就是超過 5 個 list item 之後,使用 notifyDataSetChanged 更新 list 會常常呼叫到 onCreateViewHolder,因為 inflate view 也算是有點耗時的操作,所以可以視需求決定要不要增加 view pool 容量,以減少 onCreateViewHolder 呼叫。 --- * [RecyclerView 配合 DiffUtil,好用到飞起](https://juejin.im/entry/5996977e518825242860f251) * [RecycleView性能优化](https://github.com/ChenSiLiang/android-toy/blob/master/RecycleView%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%EF%BC%88%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0%E4%B8%AD%EF%BC%89/RecycleView%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96.md) * [TextView性能瓶颈,渲染优化,以及StaticLayout的一些用处](https://www.jianshu.com/p/9f7f9213bff8) * [Instagram是如何提升TextView渲染性能的 ](http://codethink.me/2015/04/23/improving-comment-rendering-on-android/) * [Text rendering on Android](https://medium.com/@Cuong.Le/text-rendering-on-android-9a27fc59c8a6) * [StaticLayout 源码分析](https://jaeger.itscoder.com/android/2016/08/05/staticlayout-source-analyse.html) * [RecyclerView item optimizations](https://medium.com/@programmerr47/recyclerview-item-optimizations-cae1aed0c321) * [PrecomputedText New API in Android Pie](https://medium.com/mindorks/precomputedtext-new-api-in-android-pie-74eb8f420ee6)

沒有留言:

張貼留言