I'm having a lot of performance issues with SwiftUI List
s and I can't seem to find any solution. Currently, if you have a List
with 10_000
items and try to filter it, the app hangs for 1 second at the beginning of filtering, looking at Instruments it seems to be an issue with the underlying UITableView
to perform the animations.
Here's a very tiny example to demo the issue:
struct Item: Identifiable, Hashable {
let title: String
var id: String { title }
}
@main
struct ListFilteringDemoApp: App {
private let allItems = (0...10_000).map { _ in Item(title: UUID().uuidString) }
@State var searchQuery: String = ""
var filteredItems: [Item] {
if searchQuery.isEmpty {
// No filter applied
return allItems.filter { _ in true }
} else {
return allItems.filter { item in
item.title.localizedCaseInsensitiveContains(searchQuery)
}
}
}
var body: some Scene {
WindowGroup {
NavigationView {
List(filteredItems) { item in
Text(item.title).id(item)
}
.navigationTitle("Filtering")
.searchable(text: $searchQuery, placement: .navigationBarDrawer(displayMode: .always))
}
}
}
}
I know that having 10_000
items in an array is not common. But using Core Data
with a @FetchRequest
, having 10_000
items is very easy to achieve for the kind of app that I'm building, and the issue is the same.
The issue is present on device (iPhone 12 Pro, iOS 15.1), macOS and iOS Simulator.
I've two questions:
- Is there a better way to filter a list while searching?
- If the answer is no, is there any way to prevent the animations on a List while being filtered to try to improve the performance?
Thanks!
PS: For Apple folks, I've opened a feedback which includes a sample project to reproduce the issue and a saved Instruments .trace. Number: FB9763003