敏捷模板——表格视图回顾

需求分析

  • 第一版的表格性能不尽人意
  • 对接泳道
  • 调优
  • 设计

案例分析之望闻问切

如果说『表格性能不佳』, 具体的表现症状是什么 ?

  • 内存占用过多

  • 滚动丢帧

  • 界面假死

内存占用过多

滚动掉帧

假死

案例分析之对症下药

  • 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 牛顿

  1. https://github.com/facebookarchive/fixed-data-table
  2. https://github.com/bvaughn/react-virtualized
  3. https://github.com/rsuite/rsuite-table
  1. 确定设计目标,明确自己做的组件是什么
  2. 确定组件的抽象层级
  3. 确定对接的业务形态
  4. 确定验收目标

一切的开端

  1. 高效的表格模块
  2. 新视图的底层依赖
  3. 对接表格视图 & 敏捷模板的泳道视图
  4. 可以被正常使用 (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

Made with Slides.com