Search code examples
flutterdatagridcpu-usagesyncfusion

Skyrocketing cpu temps & usage only when on Syncfusion DataGrid screen in iOS emulator- Flutter


Looking for help or ideas here. Possible I'm doing something wrong or maybe someone has an idea they can help with.

I have finally figured out and successfully implemented two separate Syncfusion DataGrids. They work perfectly and do exactly what I need and want, albeit in a very complex manner compared to DataTable. Sorry had to put that plug in there. Anyway, I have the datagrid being loaded in a screen. When I go to that screen the datagrid displays and my cpu temp as well as fan speeds skyrocket very fast (one degree C every 2 seconds) until 85 degrees + where I stop the simulator or navigate to another screen. Either actions almost immediately curtail cpu temp which falls after navigation or stop. This is like clock work, navigate to datagrid screen- temps rise, navigate away- temps fall.

The culprit looks to be the "runner" as suggested by activity monitor (macbook pro) which begins using 75% + cpu.

Anyone have any helpful ideas they could suggest? I have no idea what to try, getting no outputs or errors. Also the datagrid has almost no data in it. I'm talking like 4 rows and 5 cells of super simple data... No reason this should be happening. DataTable with 50X the amount of data didn't even blip cpu...

Also question, anyone else have this issue with Syncfusion DataGrid?

EDIT: Same issue when launching with Android Studio or VS Code...

EDIT II: Running on physical iphone does not produce the same issue.

My code for the DataGrid:

//
///
/// Income data grid- Syncfusion version
import 'package:flutter/material.dart';
import 'package:fp_provider_demo_one/models/income/income.dart';
import 'package:fp_provider_demo_one/models/income/income_data.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

class IncomeDataGrid extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<IncomeData>(
      builder: (context, incomeData, child) {
        var incomeDataSource =
            IncomeGridSource(incomeData: incomeData.getIncomeList());
        return Scaffold(
          body: SafeArea(
            child: SfDataGrid(
              source: incomeDataSource,
              columnWidthMode: ColumnWidthMode.fill,
              columns: <GridColumn>[
                GridTextColumn(
                  columnName: 'source',
                  label: Container(
                    color: Colors.green,
                    padding: EdgeInsets.all(16.0),
                    alignment: Alignment.center,
                    child: Text(
                      'Source',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
                GridTextColumn(
                  columnName: 'gross',
                  label: Container(
                    color: Colors.green,
                    padding: EdgeInsets.all(8.0),
                    alignment: Alignment.center,
                    child: Text(
                      'Gross',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
                GridTextColumn(
                  columnName: 'cgi',
                  label: Container(
                    color: Colors.green,
                    padding: EdgeInsets.all(8.0),
                    alignment: Alignment.center,
                    child: Text(
                      'CGI',
                      style: TextStyle(color: Colors.white),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                ),
                GridTextColumn(
                  columnName: 'incomeDate',
                  label: Container(
                    color: Colors.green,
                    padding: EdgeInsets.all(8.0),
                    alignment: Alignment.center,
                    child: Text(
                      'Income Date',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
                GridTextColumn(
                  columnName: 'dateAdded',
                  label: Container(
                    color: Colors.green,
                    padding: EdgeInsets.all(8.0),
                    alignment: Alignment.center,
                    child: Text(
                      'Date Added',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

class IncomeGridSource extends DataGridSource {
  /// Creates the income data source class with required details.
  IncomeGridSource({@required List<Income> incomeData}) {
    _incomeData = incomeData
        .map<DataGridRow>(
          (income) => DataGridRow(
            cells: [
              DataGridCell<String>(columnName: 'source', value: income.source),
              DataGridCell<double>(columnName: 'gross', value: income.gross),
              DataGridCell<double>(columnName: 'cgi', value: income.cgi),
              DataGridCell<String>(
                  columnName: 'incomeDate',
                  value: DateFormat.yMMMd().format(income.incomeDate)),
              DataGridCell<String>(
                  columnName: 'dateAdded',
                  value: DateFormat.yMMMd().format(income.dateAdded)),
            ],
          ),
        )
        .toList();
  }

  List<DataGridRow> _incomeData = [];

  @override
  List<DataGridRow> get rows => _incomeData;

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    Color getRowBackgroundColor() {
      final int index = _incomeData.indexOf(row);
      if (index % 2 == 0) {
        return Colors.green.shade100;
      }
      return Colors.transparent;
    }

    return DataGridRowAdapter(
        color: getRowBackgroundColor(),
        cells: row.getCells().map<Widget>((e) {
          return Container(
            alignment: Alignment.center,
            padding: EdgeInsets.all(8.0),
            child: Text(e.value.toString()),
          );
        }).toList());
  }
}

Solution

  • Thank you for contacting the Syncfusion support,

    Based on your provided details and code snippet, we have analysed your reported issue. We have tried the same code snippet and our local data. We didn’t face any CPU increasing issue. We have attached the code snippet, video and system configuration details below.

    Also, we suspect that you’re creating the DataGridSource and getIncomeList consumer itself. So, may be continuous call from the provider to consumer may led to this issue. So, we did some modification on getting the data and assigned the DataGridSource to SfDataGrid in below code snippet.

    Regarding the albeit in a very complex manner compared to DataTable, we have adapted the paginated DataTable Structure of getting the widget from the user end and did the virtualizing concept in our SfDataGrid.

    Code snippet:

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'package:syncfusion_flutter_datagrid/datagrid.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider(
                create: (_) => EmployeeDataSource())
          ],
          child: MaterialApp(
            title: 'Syncfusion DataGrid Demo',
            theme: ThemeData(primarySwatch: Colors.blue),
            home: SkyRocketingIssue(),
          ),
        );
      }
    }
    
    class SkyRocketingIssue extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Consumer<EmployeeDataSource>(
          builder: (context, employeeDataSource, _) {
            return Scaffold(
              appBar: AppBar(
                title: Text('DataGrid Demo'),
              ),
              body: SfDataGrid(
                source: employeeDataSource,
                columnWidthMode: ColumnWidthMode.fill,
                selectionMode: SelectionMode.multiple,
                navigationMode: GridNavigationMode.cell,
                allowEditing: true,
                // controller: dataGridController,
                onQueryRowHeight: (details) {
                  return details.rowHeight;
                },
                columns: <GridColumn>[
                  GridTextColumn(
                      columnName: 'id',
                      label: Container(
                          padding: EdgeInsets.all(16.0),
                          alignment: Alignment.centerRight,
                          child: Text(
                            'ID',
                          ))),
                  GridTextColumn(
                      columnName: 'name',
                      label: Container(
                          padding: EdgeInsets.all(16.0),
                          alignment: Alignment.centerLeft,
                          child: Text('Name'))),
                  GridTextColumn(
                      columnName: 'designation',
                      width: 120,
                      label: Container(
                          padding: EdgeInsets.all(16.0),
                          alignment: Alignment.centerLeft,
                          child: Text('Designation'))),
                  GridTextColumn(
                      columnName: 'salary',
                      label: Container(
                          padding: EdgeInsets.all(16.0),
                          alignment: Alignment.centerRight,
                          child: Text('Salary'))),
                ],
              ),
            );
          },
        );
      }
    }
    
    /// Custom business object class which contains properties to hold the detailed
    /// information about the employee which will be rendered in datagrid.
    class Employee {
      /// Creates the employee class with required details.
      Employee(this.id, this.name, this.designation, this.salary);
    
      /// Id of an employee.
      int id;
    
      /// Name of an employee.
      String name;
    
      /// Designation of an employee.
      String designation;
    
      /// Salary of an employee.
      int salary;
    }
    
    /// An object to set the employee collection data source to the datagrid. This
    /// is used to map the employee data to the datagrid widget.
    class EmployeeDataSource extends DataGridSource {
      /// Creates the employee data source class with required details.
      EmployeeDataSource(){
        employees = getEmployeeData();
        buildDataGridRow();
      }
    
      void buildDataGridRow() {
        dataGridRows = employees
            .map<DataGridRow>((e) => DataGridRow(cells: [
                  DataGridCell<int>(columnName: 'id', value: e.id),
                  DataGridCell<String>(columnName: 'name', value: e.name),
                  DataGridCell<String>(
                      columnName: 'designation', value: e.designation),
                  DataGridCell<int>(columnName: 'salary', value: e.salary),
                ]))
            .toList();
      }
    
      List<Employee> employees = <Employee>[];
    
      List<DataGridRow> dataGridRows = [];
    
      @override
      List<DataGridRow> get rows => dataGridRows;
    
      @override
      DataGridRowAdapter buildRow(DataGridRow row) {
        return DataGridRowAdapter(
            cells: row.getCells().map<Widget>((e) {
          return Container(
            alignment: (e.columnName == 'id' || e.columnName == 'salary')
                ? Alignment.centerRight
                : Alignment.centerLeft,
            padding: EdgeInsets.all(8.0),
            child: Text(e.value.toString()),
          );
        }).toList());
      }
    
      List<Employee> getEmployeeData() {
        return [
          Employee(10001, 'James', 'Project Lead', 20000),
          Employee(10002, 'Kathryn', 'Manager', 30000),
          Employee(10003, 'Lara', 'Developer', 15000),
          Employee(10004, 'Michael', 'Designer', 15000),
          Employee(10005, 'Martin', 'Developer', 15000),
          Employee(10006, 'Newberry', 'Developer', 15000),
          Employee(10007, 'Balnc', 'Developer', 15000),
          Employee(10008, 'Perry', 'Developer', 15000),
          Employee(10009, 'Gable', 'Developer', 15000),
          Employee(10010, 'Grimes', 'Developer', 15000),
          Employee(10010, 'Lane', 'Project Lead', 20000),
          Employee(10010, 'Doran', 'Developer', 15000),
          Employee(10010, 'Betts', 'Developer', 15000),
          Employee(10010, 'Tamer', 'Manager', 30000),
          Employee(10001, 'James', 'Project Lead', 20000),
          Employee(10002, 'Kathryn', 'Manager', 30000),
          Employee(10003, 'Lara', 'Developer', 15000),
          Employee(10004, 'Michael', 'Designer', 15000),
          Employee(10005, 'Martin', 'Developer', 15000),
          Employee(10006, 'Newberry', 'Developer', 15000),
          Employee(10007, 'Balnc', 'Developer', 15000),
          Employee(10008, 'Perry', 'Developer', 15000),
          Employee(10009, 'Gable', 'Developer', 15000),
          Employee(10010, 'Grimes', 'Developer', 15000),
          Employee(10010, 'Lane', 'Project Lead', 20000),
          Employee(10010, 'Doran', 'Developer', 15000),
          Employee(10010, 'Betts', 'Developer', 15000),
          Employee(10010, 'Tamer', 'Manager', 30000),
        ];
      }
    }
    

    Configuration details:

    We have tested your reported issue the below configured mac machine

    • MacOS version enter image description here

    • Flutter Channel version

    • Flutter 2.0.3 • channel stable • https://github.com/flutter/flutter.git Framework • revision 4d7946a68d (3 weeks ago) • 2021-03-18 17:24:33 -0700 Engine • revision 3459eb2436 Tools • Dart 2.12.2*

    • XCode -> 12.4

    • Simulator iPhone 12 Pro Max version: iOS 14.4

    Please let us know the below details of your end,

    • macOS version • XCode version • Simulator version • Flutter channel version

    It will help us to analysis the reported issue on exact version.