Element 表格多选性能优化

起因

公司的基础组件库是基于 ElementUI 进行二次封装的,某天有个前端跟我反映表格组件渲染 500 条数据的情况下,多选功能的全选会变得特别卡,点一下要卡 10 几秒,我一想应该不至于啊,500 条数据量也不是特别大,怎么会卡这么久呢,会不会是他业务逻辑写得有问题,后来一测试,发现当表格的列数比较多而且结构比较复杂时,确实会让全选功能变得特别卡,那么接下来就调试分析下原因。

问题排查

Performance 分析

对于这种 js 脚本运行时间过长的问题,最好的排查方式就是利用谷歌开发者工具的 Performance 来进行排查。

打开 Performance,点击 start 开始记录,然后在表格上点击全选,等到全选效果渲染完毕,点击 stop 停止记录。

可以发现 js 脚本的大部分时间都用于执行 render 方法,而该方法就是 table-row 组件的 render 方法。

深入代码

table-row 组件用于渲染表格整一行的结构,导致 table-row 组件重新渲染的原因是组件 props 上的 isSelected 的值发生了改变。

isSelected 的值是在 table-body 组件的 rowRender 方法中通过 this.store.isSelected(row) 来确定的。

由于这个方法在内部访问了 states.selection 这个响应式属性,从而导致了依赖的收集,换而言之,只要 selection 发生了变化,就会触发 table-body 组件的重新渲染。

由于我们点击的是全选,所以可想而知重新渲染的时候所有 table-row 组件的 isSelected 属性都会发生变化,最终全部都会进行重新渲染,当表格的每一行内容比较复杂的时候,table-row 组件 render 的时间就会比较长,在行数比较多的情况下就会出现卡顿的现象。

优化方案

既然我们点击的是勾选功能,那为什么整个 table-row 组件需要重新渲染呢?能不能只重新渲染 table-row 组件内的 checkbox 组件呢?顺这个思路,就得到了一个优化方案。

因为 vue 的更新颗粒度是组件,所以可以将原先的 checkbox 封装在一个新的 table-checkbox 组件中,然后 isSelected 的值不再由父组件层层传递下来,而是在这个组件中直接通过 store.isSelected(row) 直接访问,这样之后 selection 引起的更新就只会通知到这个新的 table-checkbox 组件重新渲染了。

再谈一谈为什么 Element 不这么优化,Element 将 isSelected 的值在 table-body 组件的 render 中确定好,然后再一层一层传下来,这样当只有一行的选中状态改变时,就只会更新一个 table-row 组件,但如果采用我们这种优化方式,就算只有一行的选中状态改变了,只要 selection 变化了就会导致所有的 table-checkbox 组件更新,所以对于全选来说这种优化方法是有效的,但对于单选来说可能会比原来性能变差一点。

由于当前我们项目确实遇到了全选卡顿的问题需要解决,而 table-checkbox 组件本身比较小,所以就算单选更新所有组件也不会造成明显卡顿,所以综合考虑之后还是采用了这种优化方案。

代码地址

github.com/DLillard0/e...

相关推荐
jay神41 分钟前
基于 YOLOv8 的手势识别系统(Web 版)
前端·人工智能·python·深度学习·yolo·计算机视觉·计算机毕业设计
屏什么录43 分钟前
长时间录屏中途崩溃:MP4 打不开的 6 种救回方案与参数设置
前端·音视频开发
code_Bo1 小时前
不只命令行:我把跨 Agent 会话同步做成了桌面应用
前端·javascript·后端
kyriewen1 小时前
AI 能把页面写出来,为什么改个需求就开始崩?
前端·javascript·人工智能
涛涛ing2 小时前
2026年最值得关注的前端变化,藏在“默认值”里
前端
熊猫钓鱼>_>3 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
亿元程序员4 小时前
太牛了!这AI做出来的游戏,居然还能变现!
前端
hellice5 小时前
闪传 FlashDrop 实战:我用 300 行 Node 代码做了个「4 位取件码」临时文件中转站
前端·产品
用户0829773260055 小时前
RTX 5500 MIG 踩坑记录:切分之后模型跑不起来,排错整整一下午
前端
Lank_M5 小时前
AI 放大后的图更清楚,但它不能当原图入库
前端