我在使用 SwiftUI 时遇到性能问题 List
有大量数据。我创建了一个演示应用程序只是为了展示 500_000 String
的问题s 并显示其中一个的尾随 Action ,CPU 将在几秒钟内达到 100%,这是完全无法使用的。我也继续包装UITableView
使用相同的数据集(相同的 50 万 String
秒)在 SwiftUI 上使用它,并立即显示尾随 Action 。
有什么方法可以加快 SwiftUI 的速度 List
或者这只是框架的限制?
我只需更改名为 listKind
的变量即可轻松测试这两种实现。 ,这是示例代码:
import SwiftUI
@main
struct LargeListPerformanceProblemApp: App {
var body: some Scene {
WindowGroup {
NavigationView {
ContentView().navigationBarTitleDisplayMode(.inline)
}
}
}
}
enum ListKind {
case slow
case fast
}
struct ContentView: View {
var listKind = ListKind.slow
var items: [String]
init() {
self.items = (0...500_000).map { "Item \($0)" }
}
var body: some View {
switch listKind {
case .slow:
List {
ForEach(items, id: \.self) { item in
Text(item).swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button("Print") {
let _ = print("Tapped")
}
}
}
}.navigationTitle("Slow (SwiftUI List)")
case .fast:
FastList(items: self.items)
.navigationTitle("Fast (UITableView Wrapper)")
}
}
}
// UITableView wrapper
struct FastList: UIViewRepresentable {
let items: [String]
init(items: [String]) {
self.items = items
}
func makeUIView(context: Context) -> UITableView {
let tableView = UITableView(frame: .zero, style: .insetGrouped)
tableView.dataSource = context.coordinator
tableView.delegate = context.coordinator
return tableView
}
func updateUIView(_ uiView: UITableView, context: Context) {
uiView.reloadData()
}
func makeCoordinator() -> Coordinator {
Coordinator(items: items)
}
class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {
var items: [String]
init(items: [String]) {
self.items = items
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let printAction = UIContextualAction(style: .normal, title: "Print") { _, _, block in
print("Tapped")
block(true)
}
return UISwipeActionsConfiguration(actions: [printAction])
}
}
}
最佳答案
在仪器中分析似乎 List 为每个项目创建元数据以跟踪更改(例如插入/删除动画)。
因此,即使 List 被优化以避免创建不可见的行,它仍然具有直接 UITableView 实现不会产生的元数据开销。
List 开销的另一个演示是改为使用 ScrollView/LazyVStack 组合。我不建议将此作为替代方案(除了视觉差异之外,它会在您向下滚动列表时爆炸),但由于它不进行更改跟踪,因此它也将具有相当快的初始显示。
关于ios - 当数据集很大时,SwiftUI List 在显示操作(前导/尾随,contextMenu)方面非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68315292/