SwiftUI Scroll Performance: The 120FPS Challenge
Article Summary
Jacob Bartlett from Jacob's Tech Tavern puts SwiftUI scroll performance under the microscope. Can it really hit 120fps with complex infinite feeds, or does the magic come at too high a cost?
This deep-dive profiles three SwiftUI scrolling approaches (VStack, LazyVStack, and List) using Instruments on Low Power Mode with 1,000 complex cells. Bartlett tests both fixed and dynamic cell heights, measuring frame drops, memory usage, and real-world performance to find the smoothest solution.
Key Takeaways
- VStack caused massive 10+ second hang loading all 1,000 cells simultaneously
- LazyVStack hit 60fps but glitched badly with dynamic heights and fast scrolling
- List achieved buttery smooth 60fps even on Low Power Mode using UICollectionView
- LazyVStack improved since iOS 16 now recycles cells in both directions
- Image caching and pagination provide bigger wins than container choice alone
List outperforms LazyVStack for infinite feeds by leveraging UIKit's battle-tested UICollectionView with proper cell recycling, especially with dynamic content heights.
About This Article
Jacob Bartlett found that LazyVStack doesn't estimate dynamic heights well under pressure. When users scroll rapidly through 1,000 cells with different heights, the scroll gets glitchy and memory spikes.
Bartlett switched to List, which relies on UICollectionView and handles cell recycling properly. He also added image caching with Nuke or Kingfisher to stop AsyncImage from refetching the same images on re-renders.
List runs at a steady 60fps on Low Power Mode with only one or two frame drops during fast scrolling. LazyVStack visibly slows down in the same scenario. Memory stays flat throughout the 1,000-item scroll without any spikes.