Bad performance of large SwiftUI lists on macOS
If you want to stay with List
because you need all this nice features like selection, reordering, easy drag & drop... you will have to help SwiftUI estimate the total height of your list by having a fixed size for your rows. (I think this is the same in UIKit where performance will significantly improve if you are able to estimate the row height for each entry.)
So in your example, modify your row code as follows:
HStack {
Text("\(word.rank)")
Text(word.word)
}
.frame(width: 500, height: 15, alignment: .leading)
.tag(word)
I know it is an ugly solution because it doesn't dynamically adjust to the font size but it reduces the rendering time on my M1 Max based Mac from 2s down to 0.3s for a list of 10,000 words.
Performance issue when creating a list of 1000 elements in SwiftUI
There are a couple of issues with the code provided. The most important is you are not using a List
just a ForEach
nested in a ScrollView
, which is like equivalent of placing 1000 UIViews in a UIStack - not very efficient. There is also a lot of hardcoded dimensions and quite a few of them are duplicates but nevertheless add a significant burden when the views are calculated.
I have simplified quite a lot and it runs with n = 10000 without crashing:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
NavigationView {
ScrollView(.horizontal) {
HStack {
ForEach(0..<3) { _ in
ListView(n: 10000)
.frame(width: geometry.size.width - 60)
}
} .padding([.leading], 10)
}
}
}
}
}
struct ListView: View {
var n: Int
@State var posts = [Post(id: UUID(), title: "1", description: "11"),
Post(id: UUID(), title: "2", description: "22"),
Post(id: UUID(), title: "3", description: "33")]
var body: some View {
List(0..<self.n) { n in
RowView(post: self.posts[0])
.frame(height: 200)
}
}
}
struct RowView: View {
var post: Post
var body: some View {
HStack {
Spacer()
VStack {
Spacer()
Text(self.post.title)
Text(self.post.description)
Spacer()
}
Spacer()
} .background(RoundedRectangle(cornerRadius: 10)
.fill(Color(#colorLiteral(red: 0.721568644, green: 0.8862745166, blue: 0.5921568871, alpha: 1))))
}
}
Related Topics
Cannot Use Mutating Member on Immutable Value of Type 'string'
Using UIviewrepresentable to Wrap Marqueelabel View
How to Create a UIprintpaper to Test UIprintinteractioncontrollerdelegate
Wkwebview on Macos Cuts Off Top
How to Stop Dispatchgroup or Operationqueue Waiting
Swift 4, Simultaneous Access to Tuple Members as Inout
Connecting Avaudiosourcenode to Avaudiosinknode Does Not Work
Having Trouble with Musickit Sample App Provided by Apple
How to Name File Stored to Files App via Uactivityviewcontroller
How to Set .Realm File on Realm
Preload a Scene to Prevent Lag
Trouble Passing Array Through Prepareforsegue
How to Use Protocols for Stucts to Emulate Classes Inheritance
Convert Gregorian Date to Hijri Date
Nsundomanager: Capturing Reference Types Possible
Uicolor Extension in Swift Error