Upgrade to Pro — share decks privately, control downloads, hide ads and more …

High Performance UICollectionViewLayout

High Performance UICollectionViewLayout

In this short talk I am going through my experiences when writing UICollectionViewLayouts that need to run fast with lots of data.

Michael Ochs

July 28, 2016
Tweet

More Decks by Michael Ochs

Other Decks in Programming

Transcript

  1. The Problem • We need to support large documents (10k+

    pages) • UICollectionViewFlowLayout is slow for certain scenarios • Size calculations for each site is a slow task • UICollectionViewFlowLayout requires all sizes to be known up front* • No later than at render time
  2. The Problem • A flow layout is complex • The

    position of item i can only be calculated when all positions up to i-1 are known • Once element i is calculated, previous elements might need to be changed • The size of the collection view can only be calculated when the position of item n is known 2 3 1 5 6 4 8 9 7 11 12 10 14 15 13 17 18 16
  3. The Solution (iOS 8+) • Estimated cell sizing • All

    cells after the ones currently on screen are calculated with an estimate • This works because the collection view size is only needed to give the scroll indicator the right position and length • Caveats: • Once the delegate asks you still need to have the right size at hand • Often it makes sense to update estimates once you have calculated some sizes
  4. The Solution (iOS 8+) • Estimated cell sizing • All

    cells after the ones currently on screen are calculated with an estimate • This works because the collection view size is only needed to give the scroll indicator the right position and length • Caveats: • Once the delegate asks you still need to have the right size at hand • Often it makes sense to update estimates once you have calculated some sizes 1 2 3 4 5 6
  5. The Solution (iOS 10) • Automatic estimated cell sizing •

    Estimate is calculated based on the already known item sizes and constantly updated • Reduced amortize cost by cell prefetching
  6. The Solution (iOS 10) • Automatic estimated cell sizing •

    Estimate is calculated based on the already known item sizes and constantly updated • Reduced amortize cost by cell prefetching • Caveat: • The correct size still needs to be known when the cell is configured by the collection view
  7. Additional Features (iOS 10) • UICollectionViewFlowLayout now as automatic estimated

    cell sizing • It constantly reevaluates the estimated size based on the known cells • Often much more accurate than just providing a constant estimate • UICollectionView has UICollectionViewDataSourcePrefetching • Like cell prefetching but for the data source behind it • Collection view notifies you when to fetch data (in the background)
  8. What they don’t tell you • UICollectionViewFlowLayout does have a

    hard time for 10k+ items, no matter how much you optimize • This problem gets worse the closer you come towards the end • It’s a linear problem (at least) • They tell you start your custom layouts based on UICollectionViewFlowLayout • Don’t! Use UICollectionViewLayout • There is a s$%t load of caching going on, and chances are pretty good that their cache is not in sync with what you cache
  9. What they don’t tell you • When writing your own

    layout, cache everything • After that, cache the things you didn’t cache until now • It’s crucial to invalidate as little as possible in your caches • UICollectionViewLayoutInvalidationContext is great for that • But: You do not need to set every property there • Values like CGSizeZero do not mean 0, it really means I don’t know
  10. What they don’t tell you • Don’t invalidate you cache

    right away, wait for prepareLayout • The cycle is as follows: • shouldInvalidateLayoutFor... • invalidationContextFor... • invalidateLayout • invalidateLayoutWithContext: • prepareLayout
  11. What they don’t tell you • No matter what they

    tell you, creating a custom collection view layout that is performant is… • solving mathematical issues • not trivial • much harder than it looks