【Flutter】ListViewではshrinkWrap:trueを使うよりもSliversウィジェットを使うべき!?

こんにちは、エキサイト株式会社でアプリエンジニアをしている岡島です。今回はListViewを入れ子にする場合や、他のウィジェットと組み合わせる際に、注意すべきshrinkWrapプロパティの使用とSliversウィジェットについて取り上げたいと思います。

shrinkWrapプロパティとは

shrinkWrapプロパティは、子ウィジェットの高さに合わせて動的にListViewの高さを設定するものです。

デフォルトでは、falseになっていて、ListViewに高さの制限がない場合は、ListViewは最大サイズまで拡大されます。

shrinkWrapのtrueとfalseの違い

shrinkWrap: false(デフォルト)

  1. サイズ
    ListViewは、親ウィジェットから与えられた制約内で可能な限り大きくなります。
  2. パフォーマンス
    画面に表示されている項目のみをレンダリングするため、効率的です。

shrinkWrap: true

  1. サイズ
    ListViewは、子ウィジェットの合計高さに基づいてサイズが決定します。
  2. パフォーマンス
    すべての子ウィジェットを一度に評価するため、大量の項目がある場合はパフォーマンスが低下する可能性があります。

shrinkWrapの問題点

上記のように、shrinkWrap: trueの場合はListView表示時にレンダリングの仕組みが違います。

ListView.builderは通常、画面外のウィジェットを構築しないようになっていますが、 shrinkWrap: trueを設定すると、画面外のウィジェットも含めてすべてのウィジェットが構築されてしまいます。

そのため、リストに多数のウィジェットがある場合や、アニメーションを含む場合、パフォーマンスが著しく低下する可能性があります。

詳しくは↓こちらの動画で詳しく説明されているの ぜひご覧ください。 https://youtu.be/LUqDNnv_dh0?feature=shared

Sliversウィジェットを利用して、パフォーマンスを向上させる

shrinkWrapを使用する代わりに、Sliversウィジェットを活用することで、効率的なリスト表示を実現できます。Sliversウィジェットは、スクロール可能な領域を小さな部分に分割し、必要な部分のみを描画することでパフォーマンスを向上させます。

つまり、Sliverウィジェットを使用することで、現在の表示領域にあるウィジェットのみがレンダリングされるようになり、パフォーマンスの向上に繋がるのです。

↓サンプルコードを書いてみたので、画面描画の違いを確認してみてください。 https://dartpad.dev/embed-dart.html?id=6ac4d9e48d18129402c4ec6749731b8a

ListViewでネストを実装
SliverListでネストを実装

まとめ

今回は、ListViewのshrinkWrapプロパティの真偽値によって変わるレンダリングの仕組みを見てみました。適切に影響を理解することで、より良い実装を考えることができます。この情報が皆様のアプリ開発のお役に立てれば幸いです。ご精読いただき、ありがとうございました。