macOS 上大型 SwiftUI 列表的性能不佳

cod*_*nd1 5 macos swiftui swiftui-list

我有一个 SwiftUI 应用程序,它显示 1000 到 5000 个项目的大型列表。我注意到在 macOS 上显示如此长的列表的性能非常糟糕。SwiftUI 需要几秒钟的时间来呈现列表。这与行视图的复杂性无关。即使行只是Text()视图。

然而,在 iOS 上,相同的列表几乎会立即呈现。

我的列表视图代码如下所示:

struct WordList: View {
    
    @EnvironmentObject var store: Store
    @State var selectedWord: RankedWord? = nil

    var body: some View {
        List(selection: $selectedWord) {
            ForEach(store.words) { word in
                HStack {
                    Text("\(word.rank)")
                    Text(word.word)
                }
                .tag(word)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有人知道一些加快速度的技巧吗?或者这是 macOS 12 上的普遍问题,我们需要希望苹果在下一个主要操作系统更新中改进这个问题?

我还创建了一个非常简单的示例应用程序来测试和演示列表性能,上面的代码就取自其中。您可以在GitHub上浏览/下载

文图拉更新

文图拉 (Ventura) 上的列表性能比蒙特利 (Monterey) 有了显着改善。因此可能不需要额外的优化。

pd9*_*d95 4

如果您想继续使用,List因为您需要所有这些不错的功能,例如选择、重新排序、轻松拖放...您将必须通过为行设置固定大小来帮助 SwiftUI 估计列表的总高度。(我认为这在 UIKit 中是一样的,如果您能够估计每个条目的行高,性能将显着提高。)

因此,在您的示例中,修改行代码如下:

HStack {
    Text("\(word.rank)")
    Text(word.word)
}
.frame(width: 500, height: 15, alignment: .leading)
.tag(word)
Run Code Online (Sandbox Code Playgroud)

我知道这是一个丑陋的解决方案,因为它不会动态调整字体大小,但它可以将我基于 M1 Max 的 Mac 上的 10,000 个单词列表的渲染时间从 2 秒缩短到 0.3 秒。