web-dev-qa-db-ja.com

リストが大きい場合のReact-Native FlatListのパフォーマンスの問題

私のコードは、JSONデータを配列に取得し、FlatListを使用してデータをリストします。電話帳の写真とテキストが連続して並んでいるように見えます。

ここに私のコードがあります:

  renderItem = ({ item }) => 
    (
    <ListItem
      title={item.username}
      avatar={{ uri: item.photo }}
    />
    )


  render() {
    console.log(this.state.myData);
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.myData}
          renderItem={this.renderItem}
        />
      </View>
    );
  }

その作品と私は出力を取得しますが、パフォーマンスが遅いです。レンダリングには約10秒かかりますが、これはユーザーにとって迷惑です。高速化するにはどうすればよいですか?

8
bucsy

以下に、フラットリストを最適化するために実行できるいくつかの改善点を示します。

  1. ページネーション
    • バックエンドでデータをページ分割し、スクロールが終わりに近づいたときに再取得できます。 onEndReachedonEndReachedThresholdが役立ちます。
  2. Reactネイティブバージョンを49または最新のに更新します]
    • ファイバー16のパフォーマンスは驚くほど向上しており、すべてが高速かつスムーズに実行されます
  3. レンダーアイテムにPureComponentを使用します
    • PureComponentはコンポーネントのレンダリングとメモリ使用量を改善し、純粋なレンダリングアイテムを作成するとパフォーマンスが向上します
  4. getItemLayout prop を定義します
    • Reactは以前にそのレイアウト定義を知っているため、アイテムのレンダリングを改善します

それが役に立てば幸い

2
soutot

この回答は githubのより大きくより完全な投稿 になりました


このスレッド に従うと、reactのチームがこのパフォーマンスの問題を既に認識していることがわかります。

この問題に対する特効薬はありません。あらゆるアプローチのトレードオフと、視聴者にとって良い経験だと思うことを考慮する必要があります。しかし幸いなことに、FlatListを改善しようとすることができるいくつかの微調整があります。


用語と意味

最初は私を混乱させた多くの用語が使用されています( docs またはいくつかの問題)。それで、これを最初から邪魔にならないようにしましょう。

  • VirtualizedListFlatListの背後にあるコンポーネントで、Reactのネイティブの実装 ' 仮想リスト 'コンセプト。

  • Performanceは、このコンテキストでは、スムーズな(途切れない)スクロール(およびリストの内外へのナビゲーション)を意味します。

  • メモリ消費は、このコンテキストでは、リストに関する情報がメモリに保存されている量であり、アプリのクラッシュにつながる可能性があります。
  • 空白の領域は、VirtualizedListが十分な速度でアイテムをレンダリングできなかったことを意味するため、レンダリングされていないコンポーネントを含むリストの一部を入力します。
  • Windowこれはビューポートではなく、アイテムがレンダリングされる領域のサイズです。

小道具

FlatListを改善する1つの方法は、小道具を調整することです。以下は、そのために役立つ小道具のリストです。

removeClippedSubviews

removeClippedSubviews propをtrueに設定すると、ウィンドウの外にあるコンポーネントをアンマウントできます。

Win:これは非常にメモリフレンドリーで、常に小さなリストが表示されます。

トレードオフ:この実装には、アンマウントしないコンポーネント(例えば、ナビゲーションルート)。また、スクロールごとに膨大な量の計算が行われるため、あまり良くないデバイスで複雑なアイテムを含む大きなリストのスクロールアニメーションが途切れることもあり、パフォーマンスが低下する可能性があります。

maxToRenderPerBatch

maxToRenderPerBatch={number}を設定できます。これは、VirtualizedListに直接渡すことができるFlatListプロップです。これにより、各スクロールでレンダリングされるアイテムの次のチャンクであるバッチごとにレンダリングされるアイテムの量を制御できます。

Win:大きな数値を設定すると、スクロールするときの視覚的な空白領域が少なくなります(塗りつぶし率が向上します)。

トレードオフ:バッチあたりのアイテム数が増えるとJavaScriptのパフォーマンスが低下し、応答性が低下します(アイテムをクリックして詳細を開く)。静的で非対話型のリストがある場合、これが方法です。

initialNumToRender

initialNumToRender={number}を設定できます。これは、レンダリングするアイテムの初期量を意味します。

Win:この値は、すべてのデバイスの画面をカバーする正確なアイテム数に設定できます。これは、リストコンポーネントをレンダリングするときにパフォーマンスを大幅に向上させることができます。

トレードオフ:低いinitialNumToRenderを設定すると、空白の領域が表示される可能性が最も高くなります。

windowSize

windowSize={number}を設定できます。ここで渡される数値は、1がビューポートの高さに相当する測定単位です。デフォルト値は21で、上に10ビューポート、下に10ビューポート、その間に1ビューポートがあります。

Win:主にパフォーマンスが心配な場合は、リストをスムーズに実行し、空白を減らして、より大きなwindowSizeを設定できます。スペース。主にメモリの消費が心配な場合は、windowSizeを低く設定して、レンダリングされるリストを小さくすることができます。

トレードオフ:windowSizeが大きくなると、メモリ消費量が大きくなります。 windowSizeが低いと、パフォーマンスが低下し、空白の領域の表示の変化が大きくなります。

legacyImplementation

この小道具 、trueの場合、FlatListListViewではなく、古いVirtualizedListに依存させます。

Win:これにより、仮想化が削除され、すべてのアイテムが一度にレンダリングされるため、リストのパフォーマンスが向上します。

トレードオフ:あなたのメモリ消費は屋根に行き、複雑なアイテムを含む大きなリスト(100+)がアプリをクラッシュさせる可能性があります。また、ListViewを使用しているため、上記の調整が機能しないという警告も表示されます。

disableVirtualization

あなたは、人々がいくつかの問題でこの小道具の使用を提唱するのを見るでしょう。しかし、 これは現在廃止されています 。これはlegacyImplementationに似た何かをするために使用されていました。


リストアイテム

リストアイテムコンポーネントに関係するいくつかのwin-win戦略もあります。 VirtualizedListによって多く管理されているため、高速である必要があります。

シンプルなコンポーネントを使用する

コンポーネントが複雑になるほど、レンダリングが遅くなります。リストアイテムに多くのロジックとネストを避けるようにしてください。アプリでこのリストアイテムコンポーネントを頻繁に再利用する場合は、大きなリストだけに複製を作成し、可能な限り少ないロジックでネストをできるだけ少なくします。

軽いコンポーネントを使用する

コンポーネントが重いほど、レンダリングが遅くなります。重い画像は避けてください(リストアイテムには、できる限り小さいトリミングしたバージョンを使用してください)。設計チームに相談して、リスト内でできるだけ少ない効果と相互作用と情報を使用してください。それらをアイテムの詳細に保存します。

ShouldComponentUpdateを使用する

コンポーネントに更新検証を実装します。 ReactのPureComponentは、主に考える時間がないときに使用します。これを読んでいる場合は時間がありますので、リストアイテムコンポーネントに最も厳しいルールを作成してください。リストが十分に単純な場合は、使用することもできます

shouldComponentUpdate() {
  return false
}
21
Filipe Merker