前言
在上一篇《在线电子表格分析调研》中,我们提到了多款在线电子表格,以及阿里内部对电子表格的一些使用情况。本篇文章我们将对钉钉表格、fusion里面的表格组件及另外一款ali-react-table插件,这三款表格做进一步的性能对比。而之前提到的羽雀表格由于没有开源,我们就暂时不比较了。
性能分析工具
本文用到的性能分析工具主要是react 自身提供的 Profiler,这里我们并没有手动调用API,而是直接安装了 React Developer Tools(谷歌插件市场:chrome://extensions/) 谷歌插件就可以使用了。更多介绍可以参考《React 官方发布性能分析插件Profiler》文章
钉钉表格
示例代码
import SmartTable from '@ali/smart-table';
import { components } from '@ali/smart-table-components';
import React from 'react';
const refSheet = React.createRef();
const getFields = ((cols) => { // 生成列数据
let arr = []
for (let i = 0; i < cols; i++) {
arr.push({ "id": `${i}_$`, "name": `第${i}列`, "dataType": "text" })
}
return arr;
})(200)
const getRows = ((rows, cols) => { // 生成行数据
let arr = []
for (let i = 0; i < rows; i++) {
let field = {}
for (let j = 0; j < cols; j++) {
field[`${j}_$`] = `第${j}列第${i+1}行`;
}
arr.push({ id: i, ...field })
}
return arr;
})(2000, 200)
export default class DingTable extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
defaultValue: {
id: 'students',
showIndexField: true,
sheets: [{
"name": "名单",
"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',
}}
/>
}
}
运行截图
fusion表格
示例代码(官网地址:fusion.design/pc/?themeid…)
import Table from '@alifd/next/lib/table';
import '@alifd/next/dist/next.min.css';
import React from 'react';
const getFields = ((cols) => { // 生成列
let arr = []
for (let i = 0; i < cols; i++) {
arr.push({ "id": `${i}_$`, "name": `第${i}列`, "dataType": "text" })
}
return arr;
})(30)
const getDataSource = ((rows, cols) => { // 生成行
let arr = []
for (let i = 0; i < rows; i++) {
let field = {}
for (let j = 0; j < cols; j++) {
field[`${j}_$`] = `第${j}列第${i+1}行`;
}
arr.push({ id: i, ...field })
}
return arr;
})(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>
}
}
运行截图
ali-react-table
示例代码(github地址:github.com/alibaba/ali…)
import { BaseTable } from 'ali-react-table'
import React from 'react'
const getFields = ((cols) => { // 生成列
let arr = []
for (let i = 0; i < cols; i++) {
arr.push({ code: `${i}_$`, "name": `第${i}列`, width: 100 })
}
return arr;
})(30)
const getDataSource = ((rows, cols) => { // 生成行
let arr = []
for (let i = 0; i < rows; i++) {
let field = {}
for (let j = 0; j < cols; j++) {
field[`${j}_$`] = `第${j}列第${i+1}行`;
}
arr.push({ id: i, ...field })
}
return arr;
})(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} />
}
}
运行截图
数据对比情况
**** | 钉钉(渲染耗时:ms) | ali-react-table(渲染耗时:ms) | fusion(渲染耗时:ms) |
---|---|---|---|
1000行/20列 | 67 | 30 | 62 |
5000行/100列 | 147 | 28 | 131 |
10000行/200列 | 392 | 30 | 172 |
20000行/300列 | 1273 | 32 | 292 |
30000行/500列 | 未测出 | 31 | 414 |
卡顿情况(满分5分) | 4分 | 5分 | 5分 |
快速滚动白屏 | 明显 | 不太明显 | 明显 |
总结
- 三款表格都通过使用虚拟滚动的方式(即仅渲染屏幕内的dom节点)来加载大批量数据,不同点在于fusion表格仅支持纵向虚拟滚动,不支持横向虚拟滚动,而其他2款均支持。
- 从渲染耗时来看,虽然钉钉表格相对于其他两款耗时更长,流畅性也差一点。但是钉钉表格默认的基础配置里是支持排序、过滤、多选、增删改等操作的,无需引入额外的代码,只需配置是否开启即可。而其他两款表格仅是基础的数据展示功能,若同样配置以上功能,性能不一定会高于钉钉,这一点还需进一步验证。
- 由于ali-react-table支持了横向虚拟滚动,所以不管数据量大小渲染耗时基本都在 30ms 左右;而fusion表格随着列数的增多,耗时也会相应增加。
- 三款表格都出现了纵向快速滚动,页面白屏的情况。但相较于其他两款表格,ali-react-table的表现会好一点儿,不会出现满屏白屏,仅是浏览器底部位置部分白屏。这一点ali-react-table应该是做了优化处理。