简介

在 G 的应用中,除了画布的缩放、全局动画外,图形的更新都是个体,而之前的版本都是清理掉整个画布重新绘制所有的图形,当数据量非常大时这个成本非常大,所以在 G 4.0 中,我们将实现画布的局部渲染。

局部渲染的思考

G 要实现局部渲染,需要思考清楚下面一系列问题


局部渲染的成本

进行局部渲染时最大的成本在于:

局部渲染的成本估计


局部渲染时的问题

image.png

为了处理这种情况需要将包围盒的范围扩大,由此也带来影响更多的图形。


局部渲染的实现

裁剪

进行局部渲染时,判断需要局部渲染的图形是否在视窗内可以极大加速渲染速度,而裁剪可以进一步分为:

缓存

为了加速图形是否需要重绘,需要缓存一些计算中间结果

清理缓存

增加缓存可以有效提升渲染速度,但是当图形属性、父元素属性发生变化时清理缓存,这会增加额外的成本。

刷新局部

进行局部刷新要进行的步骤:

延迟绘制

如果用户连续调用一个图形的属性改变:

shape.attr('fill', 'red');
shape.toFront();
shape.attr('lineWidth', 2);

如果每次操作都局部刷新,性能提升有限,所以需要对局部渲染进行延迟,思路如下:

分片绘制

如果同时局部更新的区域过多,可以控制在一个帧内渲染的图形数,等待一段时间再进行下一个区域的绘制。

异常处理

局部渲染的测试

我们分别以 circle 和 path 在 1000 * 1000 像素的画布下,分别对 100, 1000, 10000, 100000 数据量进行局部渲染测试,图形的位置都是随机计算,分组包含存在矩阵和不存在矩阵的计算,结果如下:

图形类型 + 是否分组有矩阵

100

1000

10000

100000

path

0.14 / 2.5

0.23/15.8

1.03/62

13.5 / 520

circle

0.15 / 1.9

0.23/13

1.0 / 64

11 / 806

circle 分组有矩阵





path 分组有矩阵





导致局部渲染的接口

G 上的图形发生改变时会触发局部渲染,主要有几个场景:

这几方面在 Canvas、Group 和 Shape 上都有对应的接口

都会引起变化的方法

Canvas/Group

注意:addGroup 本身不会引起画布的改变

几个特殊的接口

在 Group 和 Canvas 上频繁对图形进行增删时可能会出现性能问题:

局部渲染不适合的场景


优化

局部刷新有几个核心:

优化一:是否放入局部刷新的队列


优化二:减少包围盒的比对


优化三:减少 Group 渲染


如果打标


总结

局部渲染是针对大数据量图形绘制,保证交互和动画的流畅,整体实现比较复杂,考虑的因素比较多,并不一定能够提升渲染性能,需要用户明白局部渲染的原理,在合适的场景下关闭或者打开。


未完,待续