Fabric.js谈谈效能相关
2018-11-28 13:05:08
1554次阅读
0个评论
Fabricjs 作為了个已经出来了将近 10 年的 library (from 2008),也就是 ie 还盛行的年代,经歷 web 前端技术改变的考验,到 2018 还是不停在更新著。

既然在十年前就能使用这个 Library 了,过了十年硬体设备更强大的情况下,跑起来效能绝对不是问题,或许是因為 Fabricjs 原本定位就不再做出很炫很复杂的动画效果,而是在於和使用者的互动上。

2.0.0 版本之后,图片的滤镜就能够使用 WEBGL 来做渲染,对於图片滤镜的操作效能也是一大提升。


2018/11/11 截图 - fabricjs github

不过可惜的是绘製图形还不支援 WEBGL 比较没办法及时刷新更多的图形做粒子动画。

效能调校

来看看如何调整 Fabricjs 的运作效能。

大量图形绘製

一般使用 Fabricjs 来绘製一些简单图片和 2D 形状是没有甚麼问题的。

参考 fabricjs demo - particles 绘製一千颗粒子
以及参考官方 demo 做的 10000 颗粒子 codepen
renderOnAddRemove 做大量新增/删除

当我们在做大量新增或删除时,并不想要每次新增一个图形就自动重新刷新一次画布,所以可以将 canvas.renderOnAddRemove 设為 false 但是在大量 canvas.add() 之后,需要做一次 canvas.renderAll() 来统一刷新画布。

var canvas2  = new fabric.Canvas('c2', { backgroundColor: "#000", renderOnAddRemove: false })
...省略
for (i = 10000; i >= 0; i--) {
dot = new fabric.Circle({
  left:   getRandomInt(0, 400),
  top:    getRandomInt(0, 350),
  radius: 3,
  fill:   rainbow[getRandomInt(0, rainbowEnd)],
  objectCaching: false
});
canvas2.add(dot);
}
canvas2.renderAll(); // 必要

物件快取 objectCatching

物件快取在 Fabricjs 1.7.0 之后才有的功能,预设為 true,啟用了这个物件快取后,会產生一个和你的物件一样的 Image 在你看不见的地方,在你做旋转、缩放、移动...等动作时,会使用 canvas 的 drawImage 来画出图形。

这样有什麼好处呢?

若是在处理像是 SVG 这样有复杂节点的图形,每次做旋转、缩放那些动作等於又重新要计算一次所有节点,运算起来是相当复杂又耗时的,所以 Fabricjs 提供了这个方法,使用 drawImage 指画出整个图形,就不用再让电脑重复计算复杂路径。

可以看看以下官方提供的范例,处理一个几万个 Path 的复杂 svg。

可以看到左边非常的顺畅,而右边没有快取卡到连动都动不了...

左边黄色车子设定 objectCaching = true 右边為 false


fabricjs 会在 mouseup 產生新的物件快取图片。

所以在将小的物件变大时,会看到你的图形是模糊的。



当然要不要使用 objectChaching 是可以选择的,当图形為简单不复杂的形状时,当然也是可以将 objectChaching 设為 false。

其他关於物件快取的范例
Text performance
svg cache
其他效能

这边 Fabricjs wiki 提供了一些效能调整的选项。

其实整体来说就是:
以效能渲染来说

不可被操作的物件 > 可以被操作的物件
有控制项 > 没有控制向
静态画布 > 动态画布
参考 Fabricjs - wiki
今日小结

Fabricjs 和现今其他主流 Canvas Library比较起来,以使用定位来说,对动画效能没有太多的优化,但是在 svg 图形路径上优化是还不错的。

再不做太大量物件渲染上 (10000 object up),操作起来都是顺畅的。
收藏00

登录 后评论。没有帐号? 注册 一个。