基于 Group 来做离屏渲染的原理是:
- 调用 cache 方法 , 创建一个离屏 Canvas 节点 。
- 遍历 Group 子节点进行绘制 , 同时将其绘制到离屏 Canvas 上面 。
- 下次 batchDraw 的时候判断是否有缓存 , 如果有 , 那么直接走 drawImage 的形式 。
- 比较难应用于表格这种形式的业务
- Konva 没有脏检测能力 , 即使 Group 里面的 Shape 属性改变了 , 依然不会更新离屏 Canvas 。
- 由于使用色值法来匹配图形 , 导致开启了离屏渲染 , 实际上至少要绘制四份(主canvas、事件 hitCanvas、离屏 cacheCanvas、离屏事件 cacheHitCanvas) 。
另一种场景的离屏渲染就是飞书 Bitable 里面的实现 。
飞书在底层之上封装了虚拟列表的 Widget , 也就是基于业务定制的 Widget , 这也是一种有趣的思路 。
- 创建一个虚拟列表的 Widget 类 , 将列表数据传入
- 实现列表每一项的绘制方法 , 将列表绘制出来
- 滚动的时候虚拟列表内部进行节点的回收创建 , 但不会进行异步批量渲染 , 针对可复用的部分进行离屏渲染
- 更新阶段 , 通过 key 对比来决定是回收、创建还是复用 。
多选单元格编辑器也可以基于虚拟列表实现 。
虚拟列表 Widget 类适合多维表格这种业务 , 多个视图都需要有自己的滚动容器 , 不同视图都需要处理节点的回收、复用、新建 , 通过公用 Widget 可以一步到位去支持 , 也方便在内部去做更多性能优化 。
4.3 脏区渲染对于 Konva 来说 , 每次重新渲染都是对整个 Canvas 做 clearRect 清除 , 然后重新绘制 , 性能相对比较差 。
更好的做法是检测到当前的改动影响到的范围 , 计算出重绘范围后 , 只清除重绘区的内容重新进行绘制 。
在 Canvas 中可以通过 rect 和 clip 限制绘制区域 , 从而做到只对部分区域重绘 。
以前 ECharts 底层的 ZRender 为例来讲解:
- 根据图形前后变化 , 来计算出重绘区域 , 比如上图的区域 , 在飞书文档中会将整个移动的路径当做重绘区域 。
- 如果有多个重绘区域 , 那么优先尝试将相交(包围盒)的重绘区进行合并 , 并且优先合并相交面积最大的重绘区 。
- 如果合并完成后 , 当前剩余的重绘区数量大于5 , 则进一步进行合并 , 直到数量只剩5 。
- 依次遍历这些重绘区域 , 先清除掉原有的内容 , 再进行绘制 。
除了上述的这些 , 还有在文档这边使用的一些优化手段 , 比如合并相同属性的图形绘制(线、矩形、文本等)、Canvas 分层等等 , 这些就不多做阐述了 。
5. 跨平台很多 Canvas 渲染引擎并不满足于只做 Canvas , 一般还会支持一些其他的渲染模式 , 比如 SVG 渲染、WebGL 渲染、WebGPU 渲染等等 。
在 AntV 里面通过引入对应的 package 来实现加载渲染器的 , 在 ZRender 中则是通过 register 来注册不同的渲染器 。
AntV 中使用 CanvasKit 渲染:
推荐阅读
- 浅谈前端组件设计
- |浅谈抛竿最重要的配件
- 浅谈味精最大使用量的标准 味精的主要成分是什么
- 浅谈这个风情万种的国度 土耳其的首都是什么名字
- 浅谈华硕笔记本电脑电池价格 华硕笔记本电池怎么取下来
- 浅谈班级管理的几点策略 班级管理论文
- 饵料|浅谈仲春野钓天气,好天气反而渔获差,这种时机别错过
- |浅谈职场中的沟通的重要性
- |仲春野钓鲫鱼思路浅谈,找草不是最优解,这种钓法渔获才好
- 浅谈一年级识字教学论文 识字教学论文