【SwiftUI】ScrollView + LazyVStack vs Large amounts of data

どれくらいの数のアイテムがストレスなく処理できるか。

ユーザー側の操作に問題がでるようであれば、

ページングなどそれなりの処理が必要です。

まず、シンプルに試す。

以下、1ファイルコピペして Canvas で試せます。

あれ、Gist 埋め込みのスタイル変わったか。まあいいか。



雰囲気、問題ないのは、1000個ぐらいですかね、少なめで。

なんせ、@Queryfetch() が1万個くらいになると重い。

これを元に改修していきます。

データ数は10万件にしてやってみます。

 

🤔 大量データのインポート

バックグラウンドで @ModelActor を使います。


@ModelActor
actor ItemService {
  func generate(size: Int) async {
    for i in 0 ..< size {
      modelContext.insert(
        Item(i: i, s: String(format: "%04d", i))
      )

      if ((i + 1) % 1_000 == 0) {
        try? modelContext.save()
        try? await Task.sleep(for: .milliseconds(1))
      }
    }
    try? modelContext.save()
  }
}

View の init().onAppear() で。


ItemListView()
  .onAppear {
    Task { 
      await ItemService(modelContainer: modelContext.container)
        .generate(size: 100_000)
    }

20秒くらいかかりました。

環境に依りますが、5000件/秒ぐらいです。


👉 SwiftData でのバックグラウンドでの大量データインサート #SwiftUI - Qiita hatena-bookmark

 

🤔 最終要素の表示を検出する

1000 個ずつ読み込みます。

1000個目を表示したら次の1000個を読み込みます。

この記述がシンプルで良さげです。


ScrollView {
  LazyVStack {
    ForEach(items) { item in
      Text("\(item.i) | \(item.s)")
        .onAppear {
          if item == items.last { // *
            print("load next!")
          }
        }
    }
  }
}


LazyVStack って単純に追加を繰り返すだけでもストレスなく動くんですね !

ちょっと、引っかかる感じもあるけどタイミング次第か。

( 更新中... )


関連ワード:  iOSiPhonemacmacOSSwiftSwiftDataSwiftUI今さら聞けない初心者開発