20
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUIの `LazyVStack`、`LazyHStack`、`List`: 画面に表示されたときのみビューを読み込む

Last updated at Posted at 2020-11-25

本記事は画面上に表示されたときのみデータを読み込む(遅延読み込みする)ようにSwiftUIの LazyVStackLazyHStackList を使用することについてお話しします。また、本記事では通常の VStack (非推奨です) と Form を使用した結果についてもご説明します。

遅延読み込みが必要な理由

例えば、最も人気の本を表示するアプリケーションを開発している場合、本の画像をサーバーから読み込む必要があります。

本のリストビューを表示する際、すべての本の画像が同時にダウンロードされるのを避けるべきかもしれません。代わりに、現在画面上に表示されている画像のみを読み込むのが望ましいでしょう。ユーザーがより多くの本を表示するためにスクロールすると、それらの画像がダウンロードされます。

スターターコード

完成したプロジェクトが含まれているスターターコードは、Githubからダウンロードできます。

SwiftUIがビューを読み込むタイミングをより正確に確認するために、ネットワークリクエストコードにprintステートメントがあり、そこからリクエストIDを出力します。

VStackを使用 (遅延読み込みなし)

ScrollView {
    VStack {
        ForEach(Networking.shared.getAllCatIDs(), id: \.self) { catID in
            ItemDisplay(catID: catID)
        }
    }
}

VStack の使用を選ぶと、すべてのビューが最初に読み込まれるのが分かります。このプログラムがインターネットからデータをフェッチする場合、ユーザーがプログラムを開いた時に多くのデータがダウンロードされることになります。

詳細に関してはこちらをクリックしてください
id: 99 id: 98 id: 97 id: 96 id: 95 id: 94 id: 93 id: 92 id: 91 id: 90 id: 89 id: 88 id: 87 id: 86 id: 85 id: 84 id: 83 id: 82 id: 81 id: 80 id: 79 id: 78 id: 77 id: 76 id: 75 id: 74 id: 73 id: 72 id: 71 id: 70 id: 69 id: 68 id: 67 id: 66 id: 65 id: 64 id: 63 id: 62 id: 61 id: 60 id: 59 id: 58 id: 57 id: 56 id: 55 id: 54 id: 53 id: 52 id: 51 id: 50 id: 49 id: 48 id: 47 id: 46 id: 45 id: 44 id: 43 id: 42 id: 41 id: 40 id: 39 id: 38 id: 37 id: 36 id: 35 id: 34 id: 33 id: 32 id: 31 id: 30 id: 29 id: 28 id: 27 id: 26 id: 25 id: 24 id: 23 id: 22 id: 21 id: 20 id: 19 id: 18 id: 17 id: 16 id: 15 id: 14 id: 13 id: 12 id: 11 id: 10 id: 9 id: 8 id: 7 id: 6 id: 5 id: 4 id: 3 id: 2 id: 1 id: 0

(推奨)LazyVStackの使用(またはLazyHStack

ScrollView {
    LazyVStack {
        ForEach(Networking.shared.getAllCatIDs(), id: \.self) { catID in
            ItemDisplay(catID: catID)
        }
    }
}

LazyVStack は一気に全データを読み込むものではありません。そうではなく、最大インデックス31までのデータを読み込むことになります(データを読み込む具体的な順序はありません)。ことらのログメッセージからわかるように

詳細に関してはこちらをクリックしてください
id: 21 id: 9 id: 10 id: 22 id: 1 id: 8 id: 28 id: 31 id: 13 id: 7 id: 5 id: 19 id: 15 id: 11 id: 30 id: 12 id: 14 id: 24 id: 27 id: 6 id: 23 id: 16 id: 2 id: 18 id: 29 id: 20 id: 4 id: 25 id: 17 id: 26 id: 3 id: 0

水平スタイルのディスプレイの場合には、データの表示に LazyHStack を使用することもできます。

デモプログラムをダウンロードして実際の動きをご覧ください。LazyVStack を下部にスクロールするに連れて、より多くのデータが自動的にロードされます。

(推奨)Listの使用

List(Networking.shared.getAllCatIDs(), id: \.self) { catID in
    ItemDisplay(catID: catID)
}

List を使用すると、ビューが表示された際に最初の数個のエレメントのみが読み込まれます。ビューを下にスクロールすると、自動的にさらに多くのデータが読み込まれていきます。

ログメッセージで確認できるように、LazyVStackLazyHStack と比較すると、Listではデータが順番に読み込まれていきます:

詳細に関してはこちらをクリックしてください
id: 0 id: 1 id: 2 id: 3 id: 4 id: 5 id: 6 id: 7 id: 8 id: 9 id: 10 id: 11 id: 12 id: 13 id: 14 id: 15 id: 16 id: 17 id: 18 id: 19

Formを使用

Form {
    ForEach(Networking.shared.getAllCatIDs(), id: \.self) { catID in
        ItemDisplay(catID: catID)
    }
}

また、 Form 要素内に ForEach を含めることもできます。これはビューが表示されたとき、最初の数個のデータ要素のみが読み込まれ、ユーザーがビューをスクロールダウンするにつれて追加のデータが自動的に読み込まれます。しかし、いくつかの要素が2回読み込まれているようです:

詳細に関してはこちらをクリックしてください
id: 0 id: 1 id: 2 id: 3 id: 4 id: 5 id: 6 id: 7 id: 8 id: 9 id: 10 id: 11 id: 12 id: 13 id: 14 id: 15 id: 16 id: 17 id: 18 id: 19 id: 0 id: 1 id: 2 id: 3 id: 4 id: 5 id: 6 id: 7 id: 8 id: 9 id: 10 id: 11 id: 12 id: 13 id: 14 id: 15 id: 16 id: 17 id: 18 id: 19 id: 19 id: 18 id: 17 id: 16

結論

大量のデータを読み込んで画面に表示する場合には、プログラムにおいて LazyVStackLazyHStackListビューの使用を心がけるようにしてください。これにより、必要な際にビューに関連付けられたデータが読み込まれるようになります(画面にデータを表示する場合)。


:relaxed: Twitter @MszPro

:sunny: 私の公開されているQiita記事のリストをカテゴリー別にご覧いただけます。

20
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?