SwiftUI ScrollView LazyVStack Performance

I am working with a ScrollView and a LazyVStack that can have many rows, sometimes 500 or more. My rows are expandable on tap. Performance of expand/collapse is unacceptable when the number of rows exceeds 100. The more rows, the more performance degrades.

This is the gist of my code:

Code Block
struct PlaceView: View {
/* ... */
var place: Place
@Binding expandedPlaceId: Int
var content: some View {
VStack(alignment: .leading) {
Text(place.name)
if self.expandedPlaceId.wrappedValue == place.id {
VStack(alignment: .leading) {
Text(place.city)
}
}
}
}
}


Code Block
struct PlacesListView: View {
/*...*/
@State expandedPlaceId = -1
var body: some View {
ScrollView {
LazyVStack {
ForEach(places, id: \.id) { place in
PlaceView(place: place, expandedPlaceId: self.$expandedPlaceId)
.onTapGesture { self.selectDeselect(place) }
.animation(.linear(duration: 0.3))
}
}
}
}
}



I created an init function in PlaceView with the following:

Code Block
print("calling int for place \(place.id)")


What I have noticed is when expanding, every single PlaceView calls init. For 20 or 30 PlaceView rows this is not a problem, but with several hundred views this creates a choppiness in animation and delays the expansion of the detail section.

Is there any workaround for this problem? It does not matter if I use LazyVStack or VStack (which itself is unexpected).

Here is an example project that can easily be modified to highlight the problem: https://github.com/V8tr/ExpandableListSwiftUI

In the above project, simply add the following to PlaceView.swift

Code Block
init(place: Place, isExpanded: Bool) {
        self.place = place
        self.isExpanded = isExpanded
        print("PlaceView init \(self.place.id)")
}


Post not yet marked as solved Up vote post of recursion Down vote post of recursion
3.9k views

Replies

FWIW, I've also experienced this issue, and filed it as FB8401910. LazyVStack is smooth up to a point, and then after 100 or so items it degrades to being unusable. We had to revert to using a UICollectionView wrapped in a UIViewRepresentable.

Does anyone have un update on this performance issue? Is UICollectionView still be the better option for scalable grids?

Post not yet marked as solved Up vote reply of zuma Down vote reply of zuma