简体   繁体   中英

UITableView scrolling performance problem

I am currently working as a 5 month junior ios developer.

The project I'm working on is an application that shows the prices of 70 cryptocurrencies realtime with websocket connection.

we used websocket connection, UItableview, UITableViewDiffableDataSource, NSDiffableDataSourceSnapshot while developing the application.

But right now there are problems such as slowdown scrolling or not stop scroling and UI locking while scrolling in the tableview because too much data is processed at the same time.

after i check cpu performance with timer profiler I came to the conclusion that updateDataSource and updateUI functions exhausting the main thread.

func updateDataSource(model: [PairModel]) {
    var snapshot = DiffableDataSourceSnapshot()
    let diff = model.difference(from: snapshot.itemIdentifiers)
    let currentIdentifiers = snapshot.itemIdentifiers
    
    guard let newIdentifiers = currentIdentifiers.applying(diff) else {
            return
        }
    snapshot.appendSections([.first])
    snapshot.deleteItems(currentIdentifiers)
    snapshot.appendItems(newIdentifiers)
    
    dataSource?.apply(snapshot, animatingDifferences: false, completion: nil)
}

func updateUI(data: SocketData) {
    
    guard let newData = data.data else { return }
    guard let current = data.data?.price else { return }
    guard let closed = data.data?.lastDayClosePrice else { return }
    
    let dailyChange = ((current - closed)/closed)*100
    
    DispatchQueue.main.async { [self] in
        
        if model.filter({ $0.symbol == newData.pairSymbol }).first != nil {
            let index = model.enumerated().first(where: { $0.element.symbol == newData.pairSymbol})
            guard let location = index?.offset else { return }
            model[location].price = current
            model[location].dailyPercent = dailyChange
            
            if calculateLastSignalTime(alertDate: model[location].alertDate) > 0 {
                //Do Nothing
            } else {
                model[location].alertDate = ""
                model[location].alertType = ""
            }
            
            if let text = allSymbolsView.searchTextField.text {
                if text != "" {
                    filteredModel = model.filter({ $0.name.contains(text) || $0.symbol.contains(text) })
                    updateDataSource(model: filteredModel)
                } else {
                    filteredModel = model
                    updateDataSource(model: filteredModel)
                }
            }
        }
        delegate?.pricesChange(data: self.model)
    }
}

Regards.

ALL of your code is running on the main thread. You have to wrap your entire updateUI function inside a DispatchQueue.global(qos:) , and then wrap your dataSource.apply(snapshot) line inside a DispatchQueue.main.async . the dataSource.apply(snapshot) line is the only UI work you're doing in all that code you posted.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM