对于需要快速响应和流畅滚动的场景,表格虚拟滚动可以提供更好的性能。通过减少渲染的数据量,可以减少浏览器的内存占用和重新渲染的开销,从而提高页面的响应速度和滚动的流畅性。
测试场景
- 传统的表格渲染 1w 条数据性能检测:
结论:计算、渲染性能低,页面交互卡顿
- 开启虚拟滚动方案渲染 1w 条数据性能检测:
结论:提升 6~7 倍的性能,首屏秒加载,滚动流畅。
基本介绍
虚拟滚动:可简单的理解为当数据总高度大于视口宽度时,超出视口的区域则虚拟化显示。 在滚动过程中,视口高度内的数据动态加载,新数据替换旧数据。
虚拟化:保留数据应有的高度,但不会渲染真实的 dom 结构和数据
<Table
{...props}
style={{ height: 300 }}
virtual
/>
// 配置 virtual + 表格高度即可开启虚拟滚动
横向优化
市面上的组件虚拟滚动功能基本仅支持以上纵向的虚拟处理,处理数据行的虚拟化。
企业级数据场景下,表格列数动态配置、超过 50/100 列字段等场景也很多。此时纵向虚拟处理下,初次加载渲染仍不理想,存在优化空间。
Choerodon UI Table
支持横向虚拟滚动: 当数据总宽度大于视口宽度时,超出视口的区域虚拟化显示。在横向滚动过程中,视口宽度内的数据动态加载。
<Table
{...props}
virtual
virtualCell
style={{ height: 300 }}
/>
// 配置 virtualCell 开启横向虚拟滚动`
进阶优化
优化场景
虚拟滚动并不是完美的方案。
首屏加载迅速,但基于原理,表格单元格复杂度较高时,快速滑动动态加载便会产生短暂 “空白” :
横向优化
新增横向虚拟滚动的列缓冲区和列阈值。
列缓冲区(columnBuffer)
缓冲区,顾名思义,起到缓冲的作用,对于动态加载的列来说,在滚动前左右预加载几列来作为列渲染的缓冲区域:
其次在发生横向滚动的过程中,我们需要动态加载的是视口内的列及视口外左右各加 3 列缓冲区的列数据:
缓冲区来弥补空白,优化效果:
列阈值(columnsThreshold)
观察场景,配置 columnBuffer
后,每行的 td
元素逐个变化;
分析可得,高频次的渲染 dom
对计算时间和渲染性能都有所影响。
因此新增列阈值: 以多少列进行一次渲染变化,避免粒度过小的高频次渲染;
默认定义列阈值为 3(加载列是以 3 列为阈值进行变化的),效果如下:
优化效果
开启列缓冲区 & 列阈值效果,极大优化了横向滚动时出现空白的时间及面积:
纵向优化
减少无效单元格循环。
数据量越多,单元行越多,结合字段列数越多,单元格数量剧增。
分析问题:开启虚拟滚动后,列虚拟化;但由于表格由 table
原生标签生成,存在固定列的情况下必须使用 td
进行填充,虽然 td
内没有实际的 dom
元素渲染。
分析可得: 虚拟化的列只要不在“每行”中去遍历,能大大减少无效单元格的循环所带来的时间消耗。
提前将无效的单元格遍历出来:遍历视口区域和缓冲区的单元格,渲染补充提前遍历好的单元格,这样每行减少了循环无效单元格的的时间,总时间大大的减少。
优化效果
较优化前渲染快 3 倍左右,大大减少了空白面积及空白出现的时间:
配置优化
优化后只需在 Table 上配置 virtual
属性即可开启双向虚拟滚动; columnBuffer
和 columnThreshold
属性可根据表格复杂度来配置(两个属性默认值均为 3,满足绝大部分场景的滚动效果,一般不用配置)。
<Table
// ...
virtual
columnBuffer={5}
columnThreshold={5}
style={{ height: 300 }}
/>
另外 Choerodon UI 还提供了全局虚拟滚动配置,优先级低于 Table
单独配置:
import { configure } from 'choerodon-ui';
configure({
tableVirtual: true,
tableVirtualBuffer: { columnBuffer: 3, columnThreshold: 3},
})
全局变量 tableVirtual
属性支持回调函数进行判断,开发者可根据行数(rows
)和列数(columns
)的判断来匹配项目场景:
configure({
tableVirtual: (rows, columns) => rows * columns > 3000,
})
// 当单元格数目大于3000的时候即开启虚拟滚动。
总结
Choerodon UI Table 虚拟滚动特性
-
基于原生 HTML
table
标签,原生 JS 实现 -
数据交互由 DataSet 进行管理,数据与组件耦合度小,不影响复杂表格使用场景
-
开启虚拟滚动同样支持左右固定列、行内编辑等场景
-
虚拟滚动属性配置便捷,可全局进行条件判断
深入优化总结
-
提升首次渲染时间
-
使用列缓冲区(columnBuffer) 和列阈值(columnThreshold) 优化横向虚拟滚动出现大面积空白的问题
-
通过减少无效单元格的渲染来提升了纵向虚拟滚动出现大面积空白的问题
-
优化配置,使用更灵活
使用建议
表格虚拟滚动适用于大型表格和需要高性能的场景,但对于较小的数据集或简单的表格,使用虚拟滚动可能并不必要,甚至可能引入额外的复杂性。因此,在选择是否使用表格虚拟滚动时,需要根据具体的场景和需求进行评估和权衡。
-
视口面积越小,虚拟滚动效果也越好,
TableRow
的行高越大,虚拟滚动的效果也越好。 -
对于列缓冲区(
columnBuffer
)和列阈值(columnThreshold
)的设置,columnBuffer 的值必须大于等于 columnThreshold 的值,否则横向滚动会出现明显空白。
最后
我们将持续优化 Table
的性能和交互,给客户最极致的体验。
以上就是 Choerodon UI Table 虚拟滚动的实现方案了,如果你有更好的想法和建议,欢迎您积极反馈给我们,我们诚挚的邀请您和我们一起共建 Choerodon UI,期待您的 Issue!
官网:open.hand-china.com/choerodon-u…
github:github.com/open-hand/c…