Canvas 局部渲染优化总结
简介
G2(图表引擎) 4.0 和 G6(图分析引擎) 3.4版本已经替换了 G(2D 渲染引擎)4.0,这个版本最大的改进是支持了局部渲染,在一些场景下例如节点的状态改变、图形的个体动画等方面性能提升巨大。G 4.0 从开始重构到现在稳定经历了半年的不断完善,遇到了各种各样的问题,本文将对 Canvas 的局部渲染做一个总结,给后来者一些帮助。
问题分析
由于 Canvas 的绘制方式是画笔式的,在 Canvas 上绘图时每调用一次 API 就会在画布上进行绘制一次,一旦绘制图形就成为画布的一部分。绘制图形时并没有对象保存下来,一旦图形需要更新,需要清除整个画布重新绘制。
为什么要把整个 Canvas 画布都清除,然后整体重绘?我们以上面的两张图为例,以左图为例,1, 2 没有同其他的图形重合,可以清除掉重新绘制,但是 3,4 就无法单独清理掉重绘;右图仅仅在左图的基础上增加一条折线,这时候我们就无法刷新单个图形了。
而在我们要实现局部渲染时,需要考虑的两个因素是:
- 单次刷新时影响的范围最小
- 刷新的图形不会影响其他图形的正确绘制
仅仅缩小刷新时的范围从而提升性能并不够,以右图为例,如果我们要刷新图形 2 将图形变成红色。这时候如果仅仅清理掉图形 2 ,重新绘制则:
折线就会部分消失,这与我们的预期不一致。局部刷新不但要保证刷新的范围足够小,还要保证图形绘制的正确性。
方案
我们来思考 Canvas 局部渲染方案时,需要看 Canvas 的 API 给我们提供了什么样的接口,这里主要用到两个方法:
- clip() 确定绘制的的裁剪区域,区域之外的图形不能绘制,详情查看 CanvasRenderingContext2D.clip()
- clearRect(x, y, width, height) 擦除指定矩形内的颜色,查看 CanvasRenderingContext2D.clearRect()
通过这两个 API 我们可以得到 Canvas 局部刷新的方案:
- 清除指定区域的颜色,并设置 clip
- 所有同这个