SwiftUI and AnyView: Performance benchmarks

This app illustrates real slowdown cause by AnyView.

The app
import SwiftUI

class Model {
    static let shared = Model()
    let items1K = (0 ..< 1000).map { Item(id: $0) }
    let items10K = (0 ..< 10_000).map { Item(id: $0) }
    let items100K = (0 ..< 100_000).map { Item(id: $0) }
    let items1000K = (0 ..< 1000_000).map { Item(id: $0) }
}

struct Item: Identifiable {
    var id: Int
    var text: String { String(id) }
}

struct NormalItemView: View {
    let item: Item
    
    var body: some View {
        HStack {
            VStack {
                Text(item.text)
            }
        }
    }
}

struct AnyItemView: View {
    let item: Item
    
    var body: some View {
        AnyView(Text(item.text))
    }
}

struct NormalListView: View {
    var items: [Item]
    
    var body: some View {
        List(items) { item in
            NormalItemView(item: item)
        }.listStyle(.plain)
    }
}

struct AnyListView: View {
    var items: [Item]
    
    var body: some View {
        List(items) { item in
            AnyItemView(item: item)
        }.listStyle(.plain)
    }
}

struct ContentView: View {
    private var model = Model.shared
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                NavigationLink { NormalListView(items: model.items1K) } label: { Text("NormalView 1K") }
                NavigationLink { NormalListView(items: model.items10K) } label: { Text("NormalView 10K") }
                NavigationLink { NormalListView(items: model.items100K) } label: { Text("NormalView 100K") }
                NavigationLink { NormalListView(items: model.items1000K) } label: { Text("NormalView 1000K") }
                
                NavigationLink { AnyListView(items: model.items1K) } label: { Text("AnyView 1K") }
                NavigationLink { AnyListView(items: model.items10K) } label: { Text("AnyView 10K") }
                NavigationLink { AnyListView(items: model.items100K) } label: { Text("AnyView 100K") }
                NavigationLink { AnyListView(items: model.items1000K) } label: { Text("AnyView 1000K") }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

@main struct LSTApp: App {
    var body: some Scene {
        WindowGroup { ContentView() }
    }
}

When showing a list with 1K items AnyView version is quick, with 10K items it's just a tad slower, but then it's significantly slower with 100K and 1000K items; while "normal" view version is equally fast with any number of items.

1 Like