はじめに
ページング横スクロールで3桁台の数の入力フォームを扱う要件があり、
使用ライブラリにreact-native-reanimated-carouselを選定していたのですが、ローエンドのAndroid端末で動作があまり快適でない印象を受けました。
そこで前々から動作が軽いと噂程度に聞いていたFlashListについて調べたのでまとめておきます。
FlashListとは
FlashListは、FlatListよりも軽くて高速に動作するリストビューです。
Shopifyのエンジニアによって作成され、下記を謳い文句に2022年7月にOSS化されました。
- ローエンドの端末でも60FPS以上の安定したスムーズなスクロールが可能であること
- スクロール時に未レンダリングの発生を抑えられること
- FlatListと実装の置き換えが容易であること
ネイティブの変更があるライブラリですが、Expoでもサポートされており使用できます。
また、組積レイアウトも実装できます。
なぜ軽くて高速なのか
FlashListでは、内部でRecyclerListViewというライブラリを使用しています。
RecyclerListViewではセルリサイクリングを採用しており、RecyclerListViewとFlatListはアイテムのレンダリングの仕組みが異なり、ハイパフォーマンスなスクロールを可能にしています。
セルリサイクリング
FlatListでは表示予定のアイテムのビューを常にゼロから生成します。
リストをスクロールすると新たなビューが生成され、不要になったビューは破棄されるとともにガベージコレクションが発生します。
スクロールが高速であればあるほど、生成と破棄のコストは増加し、パフォーマンスに影響を与えはじめます。
それに対して、RecyclerListViewではスクロールによってビューポートから外れたビューを破棄せず、別のアイテムの表示に再利用し、FlatListで発生していたメモリー・フットプリントの増加を防ぎます。
再利用されるコンポーネントはアンマウントされず再利用されるため、Propsとして受け取るdataやextraData以外の状態はそのまま引き継がれる点に注意が必要です。
例えば、アイテムコンポーネント内でuseStateを使用する場合には、Propsとして渡されるアイテムのデータが変わったことを検知し、Stateの書き換えが必要になるかもしれません。
他には、アイテムコンポーネント内でScrollViewを使用しているとスクロールのオフセットも引き継がれてしまう点などです。
使ってみた感想
Android端末のPixel4aで使用してみた感想になりますが、3桁程度アイテム数が増えてくるとFlatListよりも明らかにスクロールがスムーズであることが体感できました。
(面倒だったので計測とかは行ってないですが)
セルリサイクリングに注意は必要ですが、大量のアイテム一覧をスクロールするSNSやECのようなアプリの実装の際に貢献してくれるライブラリだと思います。
FlatListとの置き換えもestimatedItemSize
を指定するくらいなので、今後機会があれば使ってみたいです。
参考