目录

前言

正文

1. 虚拟滚动

1.1 介绍:

1.2 性能指标:

1.3 示例:

2. 自定义模板

2.1 提前格式化

2.2 formatter (field值发生变化时)

2.3 slots (即时)

3. 自定义单元格渲染模板的嵌套深度


前言

本篇介绍vxe-table在渲染大量数据时,渲染出现卡顿,可以提升渲染性能的几个可行性方向

正文

1. 虚拟滚动

1.1 介绍:

高性能的虚拟渲染,默认情况下,如果设置了height, max-height则会根据触发规则自动启用虚拟渲染,触发规则由scroll-x | scroll-y设置。

虚拟滚动启动后只会渲染指定范围内的可视区数据,其他的数据将被卷去收起,当滚动到可视区时才被渲染出来。

更多内容,请参考官网介绍

1.2 性能指标:

横向虚拟滚动由列宽决定性能,每一列的列宽越大就越流畅;纵向虚拟滚动由行高决定性能,每一行的高度越高就越流畅。

1.3 示例:

<vxe-table
    border
    show-overflow
    show-header-overflow
    show-footer-overflow
    show-footer
    height="300"
    :footer-method="footerMethod"
    :scroll-x="{gt: 20}"
    :scroll-y="{gt: 25}"
>

2. 自定义模板

渲染表格列时,如果启用自定义内容模板,请注意以下三种方式的性能是由高到低的,实际情况需要根据业务场景选择。详细请参考官网介绍

2.1 提前格式化

直接对源数据进行转换,性能最优,但写法相对冗余

<vxe-table :data="tableData">
  <vxe-column field="name" title="Name"></vxe-column>
  <vxe-column field="amount" title="Amount"></vxe-column>
  <vxe-column field="sex" title="Sex"></vxe-column>
  <vxe-column field="date" title="Date"></vxe-column>
</vxe-table>
export default {
	data () {
		tableData: [
		 {name: 'Test1', amount: 1024.7895, sex: '1', date: '2020-01-01T10:30:20.000+0800'},
		 {name: 'Test2', amount: 512.056, sex: '0', date: '2020-01-02T08:40:30.000+0800'}
		]
	},
	created () {
		this.tableData.forEach(item => {
			item.amount = item.amount.toFixed(2)
			item.sex = item.sex === '1' ? '男' : '女'
			item.date = XEUtils.toDateString(item.date, 'yyyy-dd-MM')
		})
	}
}

2.2 formatter(field值发生变化时)

通过formatter进行数据转换,可以在不改变数据源的情况下自动转换,仅显示为字符串

<vxe-table :data="tableData">
  <vxe-column field="name" title="Name"></vxe-column>
  <vxe-column field="amount" title="Amount"></vxe-column>
  <vxe-column field="sex" title="Sex" :formatter="fotmatSex"></vxe-column>
  <vxe-column field="date" title="Date" :formatter="formatDate"></vxe-column>
</vxe-table>
export default {
	data () {
		tableData: [
		 {name: 'Test1', amount: 1024.7895, sex: '1', date: '2020-01-01T10:30:20.000+0800'},
		 {name: 'Test2', amount: 512.056, sex: '0', date: '2020-01-02T08:40:30.000+0800'}
		]
	},
	methods: {
		fotmatSex ({ cellValue }) {
			return cellValue  === '1' ? '男' : '女'
		},
		formatDate ({ cellValue }) {
			return XEUtils.toDateString(cellValue, 'yyyy-dd-MM')
		}
	}
}

2.3 slots(即时)

如果需要自定义HTML格式内,需要用到插槽自定义格式

<vxe-table :data="tableData">
  <vxe-column field="name" title="Name"></vxe-column>
  <vxe-column field="amount" title="Amount"></vxe-column>
  <vxe-column field="sex" title="Sex">
  	<template v-slot="{ row }">
  		<span style="color: red">{{ row.sex === '1' ? '男' : '女' }}</span>
  	</template>
  </vxe-column>
  <vxe-column field="date" title="Date"></vxe-column>
</vxe-table>
export default {
	data () {
		tableData: [
		 {name: 'Test1', amount: 1024.7895, sex: '1', date: '2020-01-01T10:30:20.000+0800'},
		 {name: 'Test2', amount: 512.056, sex: '0', date: '2020-01-02T08:40:30.000+0800'}
		]
	}
}

3. 自定义单元格渲染模板的嵌套深度

从第二点可以看到,自定义单元格渲染模板是渲染性能最低的方式,但是又不得不这么做时,我们发现对性能产生影响的有两个因素,那就是单元格实际渲染的元素数量和模板内元素的嵌套深度

参考以下表格中的操作列

 渲染的时间与操作列中按钮的个数成正比,也与按钮在模板内嵌套的深度成正比,以下表格统计了渲染99行数据和4行数据时(未开启虚拟滚动时)所需时间长度:

包含99行数据的表格 包含4行数据的表格
第一次渲染所需时间 724 ms 24 ms
第二次渲染所需时间 658 ms 25 ms
第三次渲染所需时间 530 ms 23 ms
第四次渲染所需时间 548 ms 24 ms
第五次渲染所需时间 532 ms 24 ms
第六次渲染所需时间 542 ms 24 ms

如果在icon的外部再包裹一层tooltip,会加深模板内元素嵌套的深度,也会加倍渲染的时间长度。对模板的不同写法可能导致的性能问题做了以下总结:

可能影响因素 影响
有无按钮事件绑定
按钮外是否包裹tooltip 时间加倍
模板内的条件判断 v-if v-show 动态属性变量如 :disabled
按钮的个数 对提升性能有线性的影响,减少六个按钮 性能提升(6/7)*100
外层div减少一层 性能优化微乎其微

由此我们可以得出结论,渲染模板内的元素数量和元素嵌套深度都会对渲染性能造成影响,但是渲染的条件如v-if,v-else,v-show或动态属性都不会影响渲染速度。也解释了为什么使用单元格渲染器不会影响渲染性能,而仅仅只是实现了全局可复用的模板,因为渲染器的写法不会改变元素的数量和元素嵌套的深度。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐