ant-design
ant-design copied to clipboard
antd-table 存在的性能问题
What problem does this feature solve?
ant-table在生产中,在多cell & 横向滚动模式下发现有性能问题。两个css样式的box-shadow导致,这里的实现方式可能要改变下
What does the proposed API look like?
--
目前还没腾出时间准备最小复现例子,维护者们可以先吸收下这个反馈看看
在以列表为主功能区的界面内,占地面积比较大,每个cell再加点overflow:hidden这类触发重绘的css. 滑动时候就会发现阴影会被浏览器反复渲染导致掉帧。删除左右阴影的box-shadow 体感就会提升很多
https://stackblitz.com/edit/react-lplqxp?file=demo.tsx 感受不到掉帧,开到 100 数据每页也没有掉帧(显示器 60 帧) 阴影可能只是最后一根稻草?性能问题可能是别的东西导致
@muzea 棒,我会尝试在你这个例子基础上复现下;(平时忙于生存确实没做demo)
至于这个case的 提升空间:替换成一个静态image 做纵向拉伸;减少浏览器blending耗时
https://stackblitz.com/edit/react-lplqxp-q8hbgp?file=demo.tsx,index.css,index.html
@muzea 基于你的例子简单加了点复杂渲染。横向滚动肉眼可见掉帧哦
复现的关键点:有一定的DOM数同屏(因此需要把demo视窗拉拉宽,同时屏幕拉高)
- 每屏的格子数尽可能多;比如某些复杂的客户管理系统,大表格是非常常见的
- 渲染复杂(其实也没多复杂),如例子里的给每行的人打标签
我的改造点是: 每行行高28px,让纵向尽可能多容纳DOM;每页变成100个;这样尽可能多地展示信息;
现象:横滑到tag附近,掉帧尤其明显(我的电脑是2.2GHz 16GB内存 15年macbook pro)
profile下来、确实是掉帧了;
当我手动修改DOM,把里面box-shadow干掉之后;流畅极了
直接发结论:paint和rendering耗时都快被消灭了;Profile:
找到原因了,可以一起看看怎么在保留 shadow 的同时修复这个问题。
因为我有一定的native渲染经验,我大概知道这些都是来自于:
box-shadow底层实现通常有一定的硬件渲染(shader等等)、生成一些texture后。再和底下之前渲染过的内容做blending(透明度等等,需要运算来融合); 又因为阴影实现再table内,当DOM多了的时候要和每个格子都blend一遍(这个应该来自于浏览器行为,浏览器不知道scroll事件后格子是否内容发生变化,如某个格子被hover高亮了),重复运算也多了、因此就卡了;
修复建议:
- 直接使用一张渐变图可以减少硬件渲染的时间;直接blending..
- 阴影采用position absolute的方式,浮放到table兄弟节点,这样blending变成 shadow纹理 直接和 table渲染完的纹理融合,只blend一次 @afc163
@AntiMoron 学习了,我们后续找个时间试验一下
解决方案我一开始是知道的
<div> // relative
<ShadowLeft /> // absolute
<table />
<ShadowRight /> // absolute
</div>
@afc163 感谢关注!期待后续跟进
这个修复了市面上80%业务估计都有更好的体验把~
BTW: 优化后可以让我4.x的版本也发一下吗?恭喜5.0上线啊,不过我希望等一个稳定版再放业务里
我们先看看,如果能解决会在 4.x 发布。
几乎不能复现问题,仅有少数几帧出现了掉帧,大部分时候每帧都是在 16.7ms 内完成渲染的,M1 mbp,外接 4K 显示器
mbp 2015 的核显应该是 Intel® Iris® Pro Graphics 5200 这类,或许是什么硬件加速没有在这个硬件上启用? 可以在这里看看是不是有什么被关闭了 chrome://gpu/
@muzea 使用了ogl渲染;现在chrome默认都是在用硬件渲染了
据我了解m1 mbp的性能非常高;ant-design是一个非常普适性的库,如果我们机器不一样,我复现你复现不了;那我们也没法沟通到一起去了呀;
我建议还是加大这个demo的压力,找个更大的屏幕,找个更多DOM节点;我们搞搞看
so 这个问题解决了吗
@muzea 有个必现的案例,我们这边业务场景使用了单元格合并,列头有3层,一行合并10个单元格,20条数据页面就卡的不行,mbp m1的还能勉强运行,windows直接就崩了