Degraded LazyVGrid performance inside a NavigationView and a ScrollView

Originator:victor.pimentel
Number:rdar://FB9147567 Date Originated:2021-06-09
Status:Open Resolved:
Product:SwiftUI Framework Product Version:iOS 14.5
Classification:Developer Tools Reproducible:
 
**Please describe the issue:**

When a LazyVGrid is placed inside a NavigationView with big title and a ScrollView the performance gets bad very fast, especially if the item views are minimally complex, they use conditionals for building their body view and they don’t have a fixed size (like Text).

It seems that layout repaints are triggered a lot even if the view has no dependencies. Using Instruments a lot of SwiftUI layout method appear taking way too long related to StackLayout and  specially sizeThatFits.

In real devices this causes stutters when opening the screen but also when closing it and also when scrolling. If you scroll until the end, then the stutters don’t happen anymore (until you open the screen again).

I’ve attached a sample project where the issue is noticeable, but in real item views with images and more complex layout the issue gets even worse.

**Please list the steps you took to reproduce the issue:**

1. Open the attached project
2. Profile the app with Instruments using the Time Profile.
3. Check the main thread of the app, if you Invert the Call Tree and show the top functions a lot of functions related to StackLayout and sizeThatFits.

**What did you expect to happen?**

The view is not very complex, it should open smoothly and with no dropped frames when scrolling.

**What actually happened?**

Opening the detail view from a NavigationView is very resource intensive and it causes dropped frames. Also when scrolling.

Comments

Attachment, to reproduce it create an app and replace ContentView.swift with this

import SwiftUI

struct Detail: View { let items: [(key: String, value: [String])] = [ (key: "1", value: ["2", "3", "4", "5", "6", "7", "8", "9", "10"]), (key: "2", value: ["2", "3", "4", "5", "6", "7", "8", "9", "10"]), (key: "3", value: ["2", "3", "4", "5", "6", "7", "8", "9", "10"]), (key: "4", value: ["2", "3", "4", "5", "6", "7", "8", "9", "10"]), (key: "5", value: ["2", "3", "4", "5", "6", "7", "8", "9", "10"]) ]

var body: some View {
    ScrollView {
        VStack {
            Text("Lorem ipsum")

            VStack {
                ForEach(items, id: \.key) { item in
                    VStack {
                        Text("Lorem ipsum lorem ipsum \(item.key)")

                        LazyVGrid(columns: [.init(.adaptive(minimum: 150))]) {
                            ForEach(item.value, id: \.self) { text in
                                Button(action: {}) {
                                    VStack {
                                        Rectangle()
                                            .frame(height: 150)

                                        VStack {
                                            Text("Lorem Ipsum Lorem")

                                            VStack {
                                                if text.isEmpty {
                                                    Text("123456")
                                                    Text("3456")
                                                } else {
                                                    Text(text)
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    .navigationTitle("Detail")
}

}

struct ContentView: View { var body: some View { NavigationView { VStack { NavigationLink("Open Detail", destination: Detail()) } .navigationTitle("LazyVGrid Issue") } } }

By victor.pimentel at June 9, 2021, 5:58 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!