[SwiftUI] Table は lazy なのか?

SwiftUI2021

     
⌛️ < 1 min.

SwiftUI の Table は、lazy なのか確認しました。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS14.6
  • Xcode 16.1 Beta
  • iOS 17.5
  • Swift 5.9

Table

SwiftUI では、Table という表組みを表示するための View(Container) が用意されています。


参考
TableApple Developer Documentation

UIKit では、UITableView, AppKit では、NSTableView に相当するものです。

Lazy

SwiftUI に限らず、なんらかの要素をリストやテーブルに表示するときの懸念点としてその表示要素の計算量があります。

例えば、「100万要素あるデータのリストを表示する時に、100万要素分の表示要素を作り、そのうちの画面に表示される分だけを表示する」ということをしたくないということです。
現実的にも 100万要素の表示を同時に行える環境はほとんどないでしょうから、最初から表示されるであろう要素の部分だけ 表示要素を準備すれば処理を軽減できます。

MEMO

同様のことは、DB の処理でも行われます。100万要素のデータをメモリ上に読み込むのは避けたいはずで、処理するために要求されたデータのみをメモリ上に読み込み 不要なデータは読み込まないということをします。(DB として考えると通常のことです・・・)

このような必要部分のみを読み込み処理することは lazy 処理 と呼ばれ、View名に付与されていたりします。
(英語の lazy は 怠惰 の意味を持つことから、必要以上に処理しないことを指しています)

SwiftUI では、VStack / HStack と同様のレイアウトを lazy 処理 でおこなう View(Container) として、LazyVStack / LazyHStack が用意されています。


参考
LazyVStackApple Developer Documentation


参考
LazyHStackApple Developer Documentation

VStack/HStack では、このように、lazy かどうかで 別の View(Container) が用意されています。

そのほかに、Grid も lazy バージョンが用意されています。

Table は、Lazy なのか?

Table も大量のデータを扱うケースが出てきそうですので、VStack/HStack と同様な lazy 版が欲しくなります。

ですが、Table については、LazyTable という View(Container) は用意されていません。
Table が常に Lazy に処理してくれるのもありがたい振る舞いですが、ドキュメントを確認しても、lazy に振る舞うかどうかは言及されていません。

実際にサンプルコードを書いて、どのような振る舞いになっているのか確認してみました。

テストコード

以下では 必要な分だけ Row を生成しているかどうかで lazy であるかどうかの判定としています。

使用したコードは以下です。

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2024/09/02
//  © 2024  SmallDeskSoftware
//

import SwiftUI

extension Int: Identifiable {
    public var id: Int { self }
}

class Model: ObservableObject {
    var numbers: [Int] = (1..1_000_000).map({ $0 })
}

struct ContentView: View {
    @StateObject private var model = Model()
    var body: some View {
        VStack {
            Text("Hello, world!")
            Table(of: Int.self, columns: {
                TableColumn("Index") { item in
                    Text(String(item))
                }
            }, rows: {
                ForEach(model.numbers, id: \.self) { value in
                    let _ = { print("row for ", value) }()
                    TableRow(value)
                }
            })
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

1 Column しか表示していないので、List でも良いケースではありますが、あくまで目的は Table が lazy かどうかを調べることです。

iOS で確認

実行した結果は以下です。左が、スクリーンショット 右がコンソール出力です

(なお、iOS18.1beta で確認しても同じ動作でした)

iOSTable

row for  1
row for  2
row for  3
row for  4
row for  5
row for  6
row for  7
row for  8
row for  9
row for  10
row for  11
row for  12
row for  13
row for  14
row for  15
row for  16

画面に表示される分の Row のみが表示処理されています。

lazy に処理されていると言って良いと思います。

macOS で確認

実行した結果は以下です。左が、スクリーンショット 右がコンソール出力です

(なお、環境構築の関係で、macOS14.6 でのみ確認し、macOS15 beta では確認していません)

macOSTable

row for  1
row for  2
~~ 中略 ~~
row for  197
row for  198
row for  199
row for  200
row for  999899
row for  999900
~~ 中略 ~~
row for  999902
row for  999995
row for  999996
row for  999997
row for  999998
row for  999999

スクリーンショットを見てもわかりますが、表示量は、(ウィンドウサイズの関係で) iOS よりも少し少ないです。
ですが、最初の 200行分と最後の100行分が処理されています。
理由は不明です。

この状態を lazy と呼んで良いかは不明です・・・
100万行分処理されるよりは良いですが、14行のために、300行分処理されるのは、行で行われる処理によっては 問題になるかもしれません。

考察など

SwiftUI では、iOS 版ではきちんと動作するが、macOS 版では不思議な動作をするというケースが たまに見られますが、Table もその1つに思えます。

以前は そもそも 全 Row を評価するという動作だったので、あきらめて、NSTableView に切り替えたことがありましたが、その時点からは改善されているように思えます。

ただ、iOS と違って、macOS では、複数の表が同時に表示されていることが考えられるので、パフォーマンスの問題が発生した時には、疑うべき点の1つな気がします。

まとめ

Table は、Lazy なのかを確認しました。

Table は、Lazy なのか
  • iOS では、Table は lazy な動作を行う。
  • macOS では、Table は全 Row を処理はしないが、必要最小限ではない

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です