現在開発中のアプリで使用している FlatList の速度改善を行ったので、実施したことについてまとめ。
ちなみに、iOS の方が効果が分かりやすいように思えました。
Android は…個人的にはいまいちよく分かりませんでしたね…。
参考にしたのは、こちらの公式ページです。
Optimizing Flatlist Configuration · React Native
https://reactnative.dev/docs/optimizing-flatlist-configuration
追加した項目は、removeClippedSubviews
と getItemLayout
です。
まず、removeClippedSubviews
ですが、表示するデータ数が多い場合はスクロールのパフォーマンスが向上する場合があるとのことでした。
Android ではデフォルトで true
ですが、iOS ではデフォルト値が false
なので、こちらを true
に設定します。
ただし、場合によってはコンテンツが欠落するというバグが発生することがあるとのことなので、動作テストは念入りに行ってください。
私の環境では現在バグは発生していないので有効にしていますが…今後も引き続き動作テストは続けていき、もし動作が不安定になったら速攻削除します。
次に getItemLayout
ですが、こちらは FlatList
に表示する要素の高さが固定の場合にかなり有効とのことです。
レイアウトの計算を管理する必要がなくなるため、最適化に有効らしいです。
現在開発中のアプリは全データの高さが完全に同じではないのですが…とりあえず一番多い要素のコンテンツの高さに合わせて追加してみました。
今のところ、こちらも問題なく動作しているので、しばらく様子を見ようと思います。
なお、上記のサンプルコードはこちら。
const ITEM_HEIGHT = 100; <FlatList data={this.state.list} keyExtractor={item => `${item.id}`} renderItem={({item, index}) => ( <Item data={item} key={index} /> )} removeClippedSubviews={true} getItemLayout={(data, index) => ( { length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index } )} />
変数 ITEM_HEIGHT
に、リストアイテムの高さを指定します。
なお、こちらの高さは、リストアイテムの一番外側の要素に onLayout={e => console.log(e.nativeEvent.layout.height)}
を追加して取得しました。
もしかしたらもっといい方法があるのかもしれませんが…個人的にはこれが一番手っ取り早くて確実かな、と思います。
追加した設定は以上です。
あとは、環境によっては initialNumToRender
で初回に描画するリストアイテムの数を指定するのもいいと思います。
なお、あまり小さい数を指定すると、空白のエリアが表示される可能性があるとのことなので、こちらも実際に動作を確認しながら調整して実装するようにしてください。
以上、React Native で FlatList の速度改善を行う際に実施したことについてでした。
最初の方でも書きましたが、特に iOS で効果が分かりやすかったので、iOS での利用も想定している場合は是非追加してみるといいと思います!
ご参考になれば幸いです。