敏捷模板——表格视图回顾
需求分析
- 第一版的表格性能不尽人意
- 对接泳道
- 调优
- 设计
案例分析之望闻问切
如果说『表格性能不佳』, 具体的表现症状是什么 ?
-
内存占用过多
-
滚动丢帧
-
界面假死
内存占用过多
滚动掉帧
假死
案例分析之对症下药
- react-perf
- chrome elements
- chrome performance
- time API / performance API
React-perf 结果
解决方法: 分析上表中不合理的 re-render 开销, 避免不必要的重绘,此案中, 消除大部分的 tooltip 组件, 可以缓解症状。
节点数
解决方法: 在表格的场景中,每少一列就等于减少 行 X 列 的单元格,因此在这里可以暂时修改产品策略,默认只显示重要的列即可,其余列的显示与否交于用户配置。
滚动时计算
解决方法: 错误的使用 jQuery, 使得 sizzle find 的耗时极高。
render function 耗时
解决方法: 低效的实现,数组元素在单次 render 中可能会被遍历多次 (M x N)。同时 allRows 这样的属性 实际采用了 call by name 的策略,每次访问,每次计算。
- 16ms / frame = 60 fps
- render function 耗时 230 ms
- 完整耗时 4800+ ms
- 以及一些别的额外的非视图的问题
结论
所以,有这么多问题,表格能快到哪里去?
2.
从 0 开始,如何设计一个表格组件
"只要学会了哥的运营,剩下的只要A就可以了。"
—— by 前星际争霸职业选手, WCG 中国赛区亚军, 中国虫王 F91孙一峰。
"如果可以正确的设计接口、前瞻性的思考使用场景以及善用开发工具,那么写组件无非是件体力活而已"
—— by 蛤蛤蛤
"因为我站在巨人的肩上"
—— by 牛顿
- https://github.com/facebookarchive/fixed-data-table
- https://github.com/bvaughn/react-virtualized
- https://github.com/rsuite/rsuite-table
- 确定设计目标,明确自己做的组件是什么
- 确定组件的抽象层级
- 确定对接的业务形态
- 确定验收目标
一切的开端
- 高效的表格模块
- 新视图的底层依赖
- 对接表格视图 & 敏捷模板的泳道视图
- 可以被正常使用 (30 FPS +),并尽可能达到高的 FPS
复杂组件应该是分层的,因为越是业务越关注功能,而越是底层越关注实现细节,但一个好的组件应该通过正交的接口向上屏蔽这些细节。
Notes
设计底层组件的时候应当尽可能的在写 POC 时就考虑适配极端场景,因为业务逻辑必然会劣化视图的性能,而这一点我们没办法在设计之初就很好的预估。
高性能的几个细节
- 面向场景的设计 —— 虚拟化视图
- cache everything
- 尽可能的少访问布局属性
- 正确的编码方式
性能和易写的代码这 2 个主张在工程(业务实现)上是相悖的
随机数字测试的值的算法
copy from milo yip
虚拟化视图的要点
- 单个子元素的宽高必须被静态确定
- 使用 JS 来计算对应的可视区域, 而不是使用布局属性
- 提供冗余
自实现的滚动条
如果不是穷途末路, 不要写。
细节爆炸多,岂止于作死
滚动条 hover 的样式
滚动条自身的尺寸对容器的影响
当容器尺寸发生变化时, 滚动条的 handler 的重新计算
代码操作容器 scrollTop / Left 时的同步问题
...
WHY
- 跨平台样式统一
- 滚动限速
- 多 Grid 实例滚动同步问题
一些别的黑魔法
比如 auto resizer: src/common/resizer/detector.ts
通过往容器内插入一个特殊样式的元素, 当父容器大小发生变化浏览器会触发这个元素绑定 scroll 事件从而 notify 到容器尺寸发生变化的行为。
THX
agile-board
By 知白 Saviio
agile-board
- 643