Home > Enterprise >  SwiftUI List update take high CPU usage
SwiftUI List update take high CPU usage

Time:07-06

I'm developing an app, which have a small view to show download/upload items progress. I use a SwiftUI list to show them, and the transfering Row will update progress every 300ms.

The issue I meet is that when the list is growing up to 10000 line, every I change a bit on one line of the list, the CPU will run at high usage.

My Xcode version is 13.3.1 (13E500a), Simulator 15.4 iOS.

I've checked this link's solution

https://www.hackingwithswift.com/articles/210/how-to-fix-slow-list-updates-in-swiftui

This solution is not for my case, what I meet is that refreshing the List (with 20k lines) take high CPU usage. (exceed 100% on simulator)

Here is the test code


import SwiftUI

struct ContentView: View {
    @StateObject var vm = viewModel()
    @State var items = Array(1...20000)
    var body: some View {
        VStack {
            List(){
                Text(vm.itemUpdate)
                ForEach(items, id: \.self ) {
                    Text("Item \($0)")
                }
            }
//            .id(UUID())
        }
    }
}

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

class viewModel: ObservableObject {
    @Published var itemUpdate: String = ""
    init() {
        activeRefresh(interval: refreshInterval)
    }
    
    //Simulator data update every 200ms
    private var refreshTimer: Timer?
    private let refreshInterval:Double =  0.2
    private func activeRefresh(interval :Double) {
        refreshTimer = Timer.scheduledTimer(withTimeInterval: refreshInterval, repeats: true) {_ in
            self.itemUpdate = "Dynamic Item \(Int.random(in: 20000..<20100) )"
        }
    }
}


Xcode running high CPU 100% screenshot

CodePudding user response:

Using a view model object and using id:.self are usually big mistakes.

Try moving the timer to an @State in the View struct and move the string formatting code into body. Then you can remove the object.

Also you have to fix the ForEach, the correct syntax for static array of ints is ForEach(0..<1000)

CodePudding user response:

Thanks for the reply, May My demo code isn't clear to show what I meet. I'm trying use the code to show the List update slow issue.

This is trying to show the fixed item (no updating ) in list

 @State var items = Array(1...20000)

One period update item from view model

@StateObject var vm = viewModel()

I only put one simple dynamic changing String object in it, and make it timely update. Then I will see the List take almost 100% usage ,if fixed array is over 10000 , but it is working fine if the count is around hundreds

So I'm guessing the SwiftUI's List have some performance issue when the items grows

  • Related