support-library の25.0.0以降よりRecyclerViewのレンダリングパフォーマンスを向上させるItemPrefetchという機能が追加されています。
#ItemPrefetchとは
RecyclerViewでは、以下のような処理が行われています。
GPUのRenderThreadに渡っている間, UIThread はidle状態に入ります。
ここで問題となるのは、スクロールして新規にViewをinflateが必要な場合に、UIThreadでその処理が行われることによって描画遅延の原因となることです。
25.0.0より、ItemPrefetchが有効になることによって、次のViewのinflationが必要かどうかを判断し、 必要な場合はRenderThreadで描画中に次のinflationの準備を行うようになり、スムーズな描画が可能となります。
ItemPrefetchが有効になる条件としては
- support library が25以上
- Lollipop以上の端末
となります。上記の条件を満たす場合、デフォルトで有効となります。この処理はViewCacheのメモリを余分に消費するという副作用があるため、OFFにすることが可能です。その場合はLayoutManager.setItemPrefetchEnabled()
を呼び出し、falseを設定します。
詳細はDocsを御覧ください。
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html#setItemPrefetchEnabled(boolean)
#実際にどのように処理が変わっているのか
手元でRecyclerViewを使ったリストを用意し、Android Monitorに付属するパフォーマスンス計測ツールであるSysTraceで確認しました。
##ItemPrefetchが効いていない場合
赤枠に示す部分でわかるように、Viewのinflationが重たいため、処理に時間がかかっています。黄色のFはDelayがあることをWarningしています(他が5msのところ、ここは約10msかかっていました)
##ItemPrefetchが効いている場合
赤枠の部分でわかるように、RenderThreadで描画処理を実施している最中にUIThreadで次のViewをinflationしています。
#まとめ
何も特別なことをせずともRecyclerViewをSupport Library25.0.0以上に上げると自動的にItemPrefetchは適用されます。ただし25.0.0はバグがあるため、
特に制約がない限り, バグフィックスが入った25.0.1に上げることをおすすめします!