背景:
我们系统页面的表格字段比较多,有的大几十个字段,在表格数据量大的时候,表格的内存占用很大,翻页等其他操作都比较卡,购物车模型999条数据时,基本不能正常交互
于是需要解决上述问题,提高页面的执行效率、速度,降低页面的内存占用,满足大数据情况下的使用。参考了网上的一些表格优化解决方案,比如:pl-table,实现原理是:设置表格的
高度,宽度,只显示表格可视区的 单元格内容,用padding属性模拟表格的宽度,高度,或是其他占位属性。
二种选择: 1、我们可以选择 pl-table 组件改写组件库;(但是,组件库表格嵌入的地方太多,对于改表格组件来说,改动量很大风险也比较大,可能会有很多bug)
2、我们已经有表格组件的源码,只需要表格源码支持虚拟表格,就可以很轻松的实现 虚拟表格 可配置;
综合考虑了下场景,变化成本,难度、在源码基础上改动很容易实现相应的功能,而且组件库变化比较小(缺点:变动了elmentUi 表格的源码);
实现:
基于以上需求,以及原理分析,我们要实现表格 水平虚拟,垂直虚拟,水平虚拟只需要知道表格宽度 ,截取表格列数据,写一个计算方法,计算显示区应该展示什么内容就可以了。
垂直虚拟,同理截取水平数据,只是方向不同。
要实现水平滚动虚拟要解决2个难题: 1、表格列宽度是不固定的,有可能没有填写宽度,
2、要做到动态计算渲染多少个单元格可以填满可视区;
3、计算那些单元格应该在可视区渲染,并且保证滚动时,显示流畅;
[图片上传失败...(image-9ccc82-1625620708432)]

然而动态计算渲染的单元格列数,存在一个巨大的缺陷,单元格宽度是变化的,会造成单元格数量变多,减少,这样就会造成Vue会动态的创建DOM,删除DOM,而动态的创建,删除DOM,是非常消耗
页面性能的,表格还要重新渲染,造成可能卡顿或是滚动条弹跳。所以这里需要保证渲染的单元格数保持不变,只改变数据,JS是很快的。这里的问题就变成,要渲染多少个单元格可以满足覆盖可视区。
二种解决方案: 1、找出最小的单元格累加,计算要多少个单元格,比如16个可以覆盖可视区,那比它大的单元格组成的宽度,肯定大于可视区;(比较暴力,效率底)
2、模拟表格滚动过程,找出最多需要多少个单元格可以覆盖可视区;(最优解,效率最高,实现逻辑比较麻烦)
这里 选择了第二种。
最少需要渲染的单元格数相关代码:
[图片上传失败...(image-7a0783-1625620708432)]
计算展示列核心代码:

垂直虚拟,同理类似。
价值及注意点:
1、使用虚拟表格在电脑CPU不是太差的情况下,可以流畅展示上万条数据,内存占用却很小,而且保持稳定,对于大数据量页面可以采用;
2、对于大数据量页面交互,添加数据,删除数据等操作,比如购物车999条数据的增删改查,交互都是秒速完成,不会出现卡顿5-10秒甚至更长的情况;
3、集成在表格源码里,不改变原表格的API props,新增一个 是否开启 虚拟表格的 API props: horizontalVirtual 水平虚拟
但是虚拟表格也有他的不足之处:
1、需要给表格列设置宽度值,不能自动宽度,如果没有设置宽度,程序会默认设置成 100px;
2、垂直滚动虚拟时,需要给表格行设置固定高度值,不可设置动态高度;
3、太差的电脑CPU,太重的单元格组件,渲染时可能会出现卡顿现象;
4、为了降低cpu渲染开销,如果表格每页显示的数据太多,最好同时开启,水平滚动虚拟,垂直滚动虚拟:verticalVirtual 垂直虚拟
网友评论