Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Charts lib lags on scroll

I've just implemented the library Charts (https://github.com/danielgindi/Charts) in a tableview, but I experience pretty heavy lag during scrolling, when my charts hold a lot of data.

I have a method inside the ChartTableViewCell where I draw the chart based on the data I pass and call from my viewcontroller.

func updateCell(chartData: ChartData) {

    DispatchQueue.global(qos: .background).async {
        print("This is run on the background queue")
    self.readings = (readings != nil) ? readings!.readings : []
        self.period = period

        if (chartData.isKind(of: LineChartData.self)) {
            data.lineData = chartData as! LineChartData
        }
        else if (chartData.isKind(of: BarChartData.self)) {
            data.barData = chartData as! BarChartData
        }
    }

    DispatchQueue.main.async {
    self.chartView.data = data
    }
}

In my tableViewController I call the function after parsing the data:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let meta = chartMetas[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "chartCell", for: indexPath) as! ChartTableViewCell
        cell.readings = currentReadings
        cell.updateCell()

        return cell
    }

What did I miss? Since the view is lagging so hard when scrolling.

UPDATE:

I tried, as suggested, to prepare the chart data in the viewcontroller and pass it to the cell. However it seems like the problem in the resuseable cells, the lags appears when I scroll and a new cell enters the screen. How can I fix this? It is pretty annoying.

UPDATE 2: It looks like the Charts aren't supposed to be used in a tableview... https://github.com/danielgindi/Charts/issues/3395

like image 268
Recusiwe Avatar asked Apr 13 '18 15:04

Recusiwe


1 Answers

To get a serious performance boost, you'll likely need to implement UITableViewDataSourcePrefecting. By doing this, the table view will call into your delegate to let you know that a cell will be needed ahead of time. This will give your code a chance to prepare and render any data it needs.

From the documentation:

You use a prefetch data source object in conjunction with your table view’s data source to begin loading data for cells before the tableView(_:cellForRowAt:) data source method is called.The following steps are required to add a prefetch data source to your table view:

  • Create the table view and its data source.

  • Create an object that adopts the UITableViewDataSourcePrefetching protocol, and assign it to the prefetchDataSource property on the table view.

  • Initiate asynchronous loading of the data required for the cells at the specified index paths in your implementation of tableView(_:prefetchRowsAt:).

  • Prepare the cell for display using the prefetched data in your tableView(_:cellForRowAt:) data source method.

  • Cancel pending data load operations when the table view informs you that the data is no longer required in the tableView(_:cancelPrefetchingForRowsAt:) method.

like image 173
picciano Avatar answered Nov 14 '22 10:11

picciano