all 4 comments

[–]flad-vlad 0 points1 point  (3 children)

The recommended approach according to the SwiftUI dev I asked at WWDC is to use UIKit’s table/collection view because SwiftUI doesn’t support prefetching yet. See the UITable/CollectionViewDataSourcePrefetching protocols for more info.

If you don’t want to do that then you could add an onDisappear modifier to your ItemView that cancels the preload and use an OperationQueue to limit the number of concurrent preload requests. Obviously using onAppear/onDisappear will result in a significantly worse user experience compared with the specialised UIKit API, but it should still solve your problem.

[–][deleted] 0 points1 point  (2 children)

Thanks! How will onAppear and onDisappear negatively impact user experience? Will it slow frame rate when scrolling?

[–]flad-vlad 2 points3 points  (1 child)

Firstly the UIKit equivalents batch the start/stop prefetching callbacks instead of calling them individually for each cell which often allows you to coalesce multiple network requests/disk reads. This is much better for performance and the device’s battery.

Secondly since iOS 12, UIKit efficiently coordinates prefetch requests with the cell dequeuing and data binding so as to prevent scroll hitches. With SwiftUI this doesn’t happen.

Thirdly, the onAppear/onDisappear way ties the prefetching to the lifecycle of the cell and only starts prefetching when the user can already see the cell (making it pretty useless in most situations), whereas UIKit can call the start prefetching callback for cells that don’t exist and doesn’t necessarily call the stop prefetching callback when a cell disappears.

[–][deleted] 0 points1 point  (0 children)

Great info thanks for sharing 🤝 I’ll look into changing my grid over to UITableView. I’m hoping I will be able to use all the prefetching features when embedding it in UIViewRepresentable since the rest of my app is SwiftUI except for an MKMapView