简介

实现了 G 的局部渲染后,我们发现一些在视窗之外的图形会导致局部渲染的性能严重下降,需要对图形的裁剪进行分析和优化。


问题分析

局部渲染的流程

局部渲染的流程如下:


元素影响的包围盒

元素影响的包围盒并不是当前图形的包围盒,而是上次绘制时的包围盒和当前的包围盒,两个包围盒

image.pngimage.png


会出现的问题

由于我们将队列中的元素影响的包围盒合并会出现一些特殊情况:

image.png

上面的这三种情况会导致局部刷新的区域过大,本质的原因在于:


解决方案

通过上面的分析,要解决上面的问题可以增加三条规则:

则上图的三种情况变成:

image.png


进一步的优化

由于 局部性原则 ,大多数图形的变化都会发生在临近的区域、临近的节点,所以可以做进一步的优化:


原先的包围盒和新的包围盒分开处理

图形/分组的变化需要考虑绘制前的包围盒和当前的包围盒,默认的方案中会对这两个包围盒进行合并,这种合并本身会带来很大的问题,同前面出现的情况类似:

image.png


如果在合并前对包围盒加一个判定,如果未在视窗内的包围盒不参与合并,则上面几种情况会发生如下变化:

image.png

我们可以看到第一种情况和最后一种情况并没有改善,如果两者不合并则会变成:

image.png

但是假如不合并则会出现一些问题:

image.png

更多的情况下图形元素的改变是局部的,原始的包围盒与改变后的包围盒会相交或者包含,所以从实践上来看两者包围盒合并是一种合适的策略。

类似的场景

如果两个图形分别贯穿横向和纵向,按照默认的方案,会导致整个画布刷新。

image.png

视窗和刷新包围盒的裁剪

当刷新区域和当前画布的视窗差异很大时,需要考虑视窗和绘制区域的相交处理:

image.png

同视窗相交后的绘制区域变化为:

image.png

如果不在视窗内的图形不参与刷新,则上面可以继续优化成:

image.png

需要刷新的区域更小


总结

我们可以对包围盒的合并策略、画布视窗的裁剪对局部渲染进行更多的优化,但是需要在优化时考虑一个场景出现的频率(可能性),否则会出现过度优化的情况,性能不升反降。

优化是无止境的,何时停止才是真正的考验!