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:
With Empty Snapshot
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
Without Empty Snapshot
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:
- first time loading: it's quicker without creating and applying empty snapshot, 1.25 vs 1.36
- subsequent loading: applying empty snapshot before applying full-size snapshot is much quicker than just applying full-sized one, because it saves time to calculate the diff between two full-sized snapshots.
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.
Using
dataSource.applySnapshotUsingReloadData()is much faster thanapply(_, 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.https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource/3804469-applysnapshotusingreloaddata
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: