G6 3.3 性能战斗机

710 阅读8分钟

本文作者:十吾

🌈G6 3.3 正式版今日正式发布。

AntV G6 是一款开源的图可视化引擎,专注于图可视化及图分析领域。 欢迎关注和 star 我们的 GitHub:github.com/antvis/G6 官网:g6.antv.vision/zh/


图——实体与关系的集合,往往具有庞大的数据量。最常见的图可视化将关系数据绘制为大量节点和边元素,而每一个元素也可能由多种图形复合而成,例如最为常见的带文本节点。图元素的样式变化万千,渲染、交互性能一直是关系数据可视化中最为棘手问题之一。特别是在前端计算资源有限的情况下,如何提升图可视化的性能,成为 G6 一大难题。

2020 年伊始,我们终于向着这一难题跨出了第一步 —— 性能卓越的 G6 3.3 正式发布。让我们一睹性能战斗机的究竟吧!

战斗机之引擎

G6 本次性能升级主要归功于底层渲染引擎的全面升级。由于用户在对图进行交互时,往往是对局部元素进行操作,例如:更新样式、拖拽…。而频繁的渲染是 G6 性能较低的主要因素。因此,我们使用「局部渲染」机制替代了以往的全局渲染。

image.png

什么是局部渲染?如上图所示,我们希望更新图 a 中的星形的填充色为绿色:

  • 全局渲染:将会如图 b 所示重新绘制由红色边框标识的整个画布;
  • 局部渲染:首先计算需要更新的图形的最小包围盒,即图 c 所示的红色边框标识区域,并仅重新绘制该包围盒范围内的画布。

image.png

类似地,拖拽元素时也涉及到画布的频繁刷新。如上图,在拖拽星形过程中,局部渲染将只涉及到星形本身以及被它遮盖到的其它图形。

由于前端 Canvas 渲染效率低下,这种局部渲染机制大大提高了效率,特别是在图上元素数目庞大、更新频繁的情况中。但我们也要承认局部渲染需要额外进行包围盒计算的开销。

战斗演习

了解了战斗机引擎构造后,现在让我们进入性能战斗机演习阶段。

演习一:小试牛刀

数据 Net-Science 有 1589 个节点,2742 条边。描述了科研工作中论文作者之间的合作关系。节点代表论文作者,若两个作者之间存在合作,则两个节点间存在一条边。

概览

使用 G6 绘制该数据,节点大小映射了其度数大小。我们可以发现有很多离散节点,代表了这些学者或许是“极客独行侠”。另外,图上有一些有趣的局部结构,例如绿色线框中度数较高的节点,代表了该学者与许多学者有合作;红色线框标注的全连接子图(clique),代表这一群学者合作关系十分紧密,两两之间都存在过合作。

用户希望通过交互了解这些特殊的结构,如拖拽单个节点以了解该节点的连接情况、拖拽子图将其放置在其他位置、标注节点的名称等。

image.png

实验

为了更好地展示每个节点的具体信息,往往需要为节点添加文本。文本是 Canvas 渲染中的性能消耗大鳄,且节点上的文本可能很长。若每个节点带有一个文本标签,则该图有 1,589 * 2 + 2,742 = 4331 个图元

现在,我们测试 G6 拖拽单个节点与一群节点的性能。由于该数据量不算巨大,使用 G6 3.2 及之前的版本对单个节点拖拽的交互体验仍能接受,但仔细观察会发现被拖拽的节点并不能很好地跟随鼠标,帧率较低。而 G6 3.3 在有复杂文本的情况下仍能保证顺滑的拖拽效果。

netscience-drag-big.gif

演习二:披荆斩棘

数据 Eva 有 8,343 个节点,6,726 条边,描述了美国一些公司之间的从属关系。一个节点代表一个公司,若公司 A 为公司 B 的拥有者,则两个节点之间存在一条边。

概览

同样,节点大小映射了其度数大小。除了有诸多离散在外圈的单个节点外,图中有许多度数很高的节点,其邻居节点放射状分布在其周围。用户可能希望通过拖拽重新规划某些节点、某群节点的位置,从而能够更清晰地观察详细结构。

image.png

实验

在这个实验中,每个节点带有一个文本标签,即该图有 8,343 * 2 + 6,726 = 23,412 个图元。现在我们测试拖拽一群节点到新到位置时,从鼠标开始拖动到完成响应所耗时长。我们发现在 G6 3.2 及之前的版本中,由于响应速度太慢,导致几次拖拽都没有成功,最后一次在鼠标移动非常缓慢时才勉强被拖动,交互体验极差。而 G6 3.3 中拖拽非常顺畅。

eva-drag-group-big.gif

现在,我们测试在鼠标移动过程中节点通过样式变化响应鼠标的 hover,可以看到 G6 3.3 中的响应速度更快、帧率更高:

eva-hover-big.gif

演习三:冲云破雾

数据 “模拟大规模系统调用树” 为树图,具有 440 个节点,439 条边。每个节点上具有丰富的信息。一个节点代表了系统中的一个模块,两个模块之间若存在调用关系,则两节点之间存在一条边。

概览

该数据的每个节点上具有丰富的信息,因此一个节点是 9 种图形的组合;每条边也由 3 个图形组合而成。这意味着图上有 440 * 9 + 439 * 3 = 5277 个图元,其中,有约 42% 为极耗性能的文本图形。边被表达成贝塞尔曲线,这意味着在更新每一条边时,要比直线更多的计算量。且一条贝塞尔曲线的包围盒较之于一条直线要更大,因此局部渲染需要重绘的范围也更大。换句话说,使用非直线的边将会更加消耗性能。

image.png

从下图可以发现,图的范围极大,一屏完全无法展示。用户必须通过交互进行探索。当鼠标进入边或节点时,相应的图形通过样式的变化进行响应。而非叶子节点可以进行展开、收缩操作。

complex-tree-overview.gif

实验

首先,我们对比在鼠标进入/离开边或节点时,图形做出响应的帧率。

  • 边的 hover 响应:可以发现在 G6 3.2 及之前的版本中,边的响应非常慢,甚至在鼠标滑过的速度过快时,没有做出响应,其帧率约 5.5~8.6fps;而在 G6 3.3 中,边响应速度较快,帧率约 12.9~22.6 fps。这是由于 G6 3.3 的引擎不仅做到了局部渲染,还优化了非直线路径的拾取效率。
  • 节点的 hover 响应:G6 3.2 及之前的版本帧率约为 7.1~10.3 fps,有明显卡顿感;而 G6 3.3 的帧率约为 23.4~32.5fps,非常顺滑。

complex-tree-hover-big.gif


接下来,我们对比在该大规模树上进行子树的折叠/扩展效率。G6 3.2 及之前的版本中,折叠/扩展动画有明显的卡顿感,帧率约 6.2~9.4fps。而 G6 3.3 的折叠/扩展动画顺滑,帧率为 20.1~34.4 fps。

complex-tree-collapse-big.gif

战斗机——“折翼的天使”

现在,G6 的性能还只能算是“折翼天使”。虽然有了强大的引擎,但在上层还有很大的优化空间。例如减少不必要的深复制、优化边的重计算等。这将是性能战斗机真正能够高速翱翔的强健机翼,我们将会持续打造更强悍的图可视化战斗机。

夹带私货

G6 3.3 除了性能显著提升外,我们还有以下新特性:

  • 全面拥抱 TypeScript;
  • 处理拖拽节点/画布超出画布的情况;
  • 更自由的元素与布局配置;
  • 更丰富的构建产物。

G6 3.3 初步解决了困扰我们已久的性能问题,对 TS 开发者更加友好。同时,处理了交互上的多种复杂情况。G6 社区正在逐步扩大,它将更加开放、自由地迎接来自社区的共建。欢迎您的加入!

G6 从 2017 年发展至今,从 1.0.0 迭代到 3.3.0,这过程中有哪些经历和思考,请参考 AntV 架构演进-G6 篇

AntV G6 是一款开源的图可视化引擎,专注于图可视化及图分析领域。 欢迎关注和 star 我们的 GitHub:github.com/antvis/G6 官网:g6.antv.vision/zh/

g6-gallery.png