preface

In our last article, Online Spreadsheet Analysis Research, we mentioned the various online spreadsheets and some of the internal use of spreadsheets at Alibaba. In this article, we’ll take a closer look at the performance of the pinned table, the Table component in Fusion, and another ali-React-Table plugin. The table of finches mentioned earlier is not open source, so we will not compare them.

Performance analysis tool

This article uses the React Profiler, which is provided by the React Profiler itself. Instead of calling the API manually, you can install the React Developer Tools (Google Chrome :// Extensions /) to use the Profiler. For more information, see the React Official release Profiler

Nailing form

The sample code

import SmartTable from '@ali/smart-table';
import { components } from '@ali/smart-table-components';
import React from 'react';

const refSheet = React.createRef();


const getFields = ((cols) = > { // Generate column data
  let arr = []
  for (let i = 0; i < cols; i++) {
    arr.push({ "id": `${i}_ $`."name": The first `${i}Column `."dataType": "text"})}returnarr; }) (200)

const getRows = ((rows, cols) = > { // Generate row data
  let arr = []
  for (let i = 0; i < rows; i++) {
    let field = {}
    for (let j = 0; j < cols; j++) {
      field[`${j}_ $`] = The first `${j}The column first${i+1}Line `;
    }
    arr.push({ id: i, ... field }) }returnarr; }) (2000.200)

export default class DingTable extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      defaultValue: {
        id: 'students'.showIndexField: true.sheets: [{
          "name": "A list"."fields": getFields,
          "rows": getRows,
        }],
        
        allowSelector: false.allowSort: true.allowFilter: true.allowGroup: true.allowAggregate: true.allowEditCell: false.allowRenameField: true.allowDeleteField: true.allowChangeFieldDataType: true.allowMoveField: true.allowResizeField: true.allowInsertField: true.allowInsertRow: true.allowDeleteRow: true.allowSelectRow: true.showHeaderCellMenu: true.showSummaryBar: true,
      },
    }
  }
  
  render () {
    return <SmartTable
      ref={refSheet}
      defaultValue={this.state.defaultValue}
      components={components}
      shouldSetCell={async (values) = > {
        return true;
      }}
      style={{
        width: '100vw',
        height: '500px',
      }}
    />}}Copy the code

Run a screenshot

The fusion form

Sample codeThe fusion. The design/PC /? Themeid…)

import Table from '@alifd/next/lib/table';
import '@alifd/next/dist/next.min.css';
import React from 'react';

const getFields = ((cols) = > { / / generated columns
  let arr = []
  for (let i = 0; i < cols; i++) {
    arr.push({ "id": `${i}_ $`."name": The first `${i}Column `."dataType": "text"})}returnarr; }) (30)

const getDataSource = ((rows, cols) = > { / / generated
  let arr = []
  for (let i = 0; i < rows; i++) {
    let field = {}
    for (let j = 0; j < cols; j++) {
      field[`${j}_ $`] = The first `${j}The column first${i+1}Line `;
    }
    arr.push({ id: i, ... field }) }returnarr; }) (10000.30)


export default class NextTable extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      dataSource: getDataSource,
      columnData: getFields,
    }
  }
  
  render () {
    return <Table dataSource={this.state.dataSource} useVirtual maxBodyHeight={500}>
      {
        this.state.columnData.map((column, index) => {
          return <Table.Column width={100} title={column.name} dataIndex={` ${index}_$`} / >})}</Table>}}Copy the code

Run a screenshot

ali-react-table

Github address:Github.com/alibaba/ali…)

import { BaseTable } from 'ali-react-table'
import React from 'react'

const getFields = ((cols) = > { / / generated columns
  let arr = []
  for (let i = 0; i < cols; i++) {
    arr.push({ code: `${i}_ $`."name": The first `${i}Column `.width: 100})}returnarr; }) (30)

const getDataSource = ((rows, cols) = > { / / generated
  let arr = []
  for (let i = 0; i < rows; i++) {
    let field = {}
    for (let j = 0; j < cols; j++) {
      field[`${j}_ $`] = The first `${j}The column first${i+1}Line `;
    }
    arr.push({ id: i, ... field }) }returnarr; }) (10000.30)

export default class AliReactTable extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      dataSource: getDataSource,
      columnData: getFields,
    }
  }
  
  render () {
    return <BaseTable dataSource={this.state.dataSource} useVirtual columns={this.state.columnData} />}}Copy the code

Run a screenshot

Data comparison

* * * * Nail (Render time: ms) Ali-react-table (render time: ms) Fusion (Render time: ms)
1000 line / 20 columns 67 30 62
5000 line / 100 columns 147 28 131
10000 line / 200 columns 392 30 172
20000 line / 300 columns 1273 32 292
30000 line / 500 columns Not measured 31 414
Stuck situation (out of 5 points) Four points 5 points 5 points
Quickly scroll the white screen obvious Less obvious obvious

conclusion

  1. All three tables use virtual scrolling (rendering only dom nodes on the screen) to load large amounts of data. The difference is that the Fusion table only supports vertical virtual scrolling, not horizontal virtual scrolling, whereas the other two tables do.
  2. In terms of rendering time, the pin table takes longer and is less smooth than the other two. However, the default base configuration of the pin table is to support sorting, filtering, multiple selection, add, delete, change and other operations, without introducing additional code, just configure whether to enable. The other two forms are only basic data display functions. If the above functions are configured, the performance may not be higher than that of the nail, which needs further verification.
  3. Since ali-React-Table supports horizontal virtual scrolling, rendering takes about 30ms regardless of the amount of data. The fusion table takes more time as the number of columns increases.
  4. All the three forms showed vertical fast scrolling and white screen. However, compared to the other two tables, Ali-React-Table performs a little better. It does not display a full blank screen, but only a partial blank screen at the bottom of the browser. Ali-react-table should be optimized for this.