Reputation: 5341
I have a UICollectionView with a large set of data source, e.g. 30000+ items; And the data source varies depending on screen orientation (ie. portrait, landscape), so I re-create and re-apply the snapshot whenever screen rotates.
What I noticed, is that the first time UICollectionView
loads cells it's relatively quick, but subsequently re-applying different snapshots (after screen rotation) takes a long time.
This is understandable because subsequent reload need lots of computing for the diff of existing and new snapshots, so I wonder, if there's a way to apply snapshots without calculating the diffs? I don't want to keep two copies of snapshot in memory because of the size of them. Or can I workaround this by first applying an empty snapshot before applying the full sized one?
Thanks!
Edit:
I did some rough test:
First Load:
2022-08-05 07:47:11.666847+1000 before apply
2022-08-05 07:47:11.667139+1000 after apply empty snapshot
2022-08-05 07:47:11.788821+1000 after creating full-sized snapshot
2022-08-05 07:47:13.022973+1000 after applying full-sized snapshot
total: ~1.36
Reload after rotation:
2022-08-05 07:48:05.238174+1000 before apply
2022-08-05 07:48:08.708084+1000 after apply empty snapshot
2022-08-05 07:48:08.900322+1000 after creating full-sized snapshot
2022-08-05 07:48:12.034542+1000 after applying full-sized snapshot
total: ~6.80
First Load:
2022-08-05 07:49:33.149233+1000 Setting columns…
2022-08-05 07:49:33.279147+1000 before apply
2022-08-05 07:49:33.401114+1000 after creating full-sized snapshot
2022-08-05 07:49:34.402645+1000 after applying full-sized snapshot
total: ~1.25
Reload after rotation:
2022-08-05 07:50:26.829309+1000 Reload due to trait collection change…
2022-08-05 07:50:27.270996+1000 Setting columns…
2022-08-05 07:50:31.187630+1000 before apply
2022-08-05 07:50:31.410154+1000 after creating full-sized snapshot
2022-08-05 07:50:45.879088+1000 after applying full-sized snapshot
total: ~19.05
Conclusion:
So the question remains: is there any way to make it quick? If not I may need to go back to the old UICollectionViewDataSource
way of providing cells.
Upvotes: 1
Views: 691
Reputation: 338
Using dataSource.applySnapshotUsingReloadData()
is much faster than apply(_, animatingDifferences: )
and is especially for the case where you are changing a lot of data because it does not compute a diff. I eliminated a 3+ second lag in my own code handling 30k+ rows by making this change.
Note that it is only available on iOS 15 or later, so if you still need to support older versions you may need to wrap as such:
if #available(iOS 15, *) {
self?.dataSource.applySnapshotUsingReloadData(snapshot)
} else {
self?.dataSource.apply(snapshot, animatingDifferences: false)
}
Upvotes: 0