The following has a SwiftUI Hang for several seconds.
This code is copy-pasted and makes up one of the tabs of my simple app. Hang occurs once when first showing this tab.
Number of images is ~150; image size 1920x1080.
struct PhotosView : View
{
@FetchRequest(sortDescriptors: [SortDescriptor(\Photo.date, order: .reverse)], animation: .default)
private var photos: FetchedResults<Photo>
@State private var gridHeight = 180.0
var body: some View
{
VStack
{
ScrollView(.horizontal)
{
LazyHGrid(rows: [GridItem(.fixed(gridHeight))], alignment: .top, spacing: 0)
{
ForEach(photos)
{ photo in
if let data = photo.filteredData
{
Image(data: data)
.resizable()
.scaledToFit()
}
}
}
.frame(height: 200)
}
}
}
}
I thought that using the LazyHGrid
only a handful would be loaded initially (only one and almost a half fit on screen currently).
How I can improve performance?
By default the fetch will load every
filteredData
into memory even if it is not being displayed. You need to use a customNSFetchRequest
withincludesPropertyValues
set tofalse
and then make a subview that takes the object and accessesfilteredData
causing it only to be loaded for that one object when it appears (body
will be called at this time). You would also benefit from a predicate that searches for non-nil data that would help avoid theif
in yourbody
which can cause slow downs. E.g. something like:See my answer to another question for more detail.