Fabric.js谈谈效能相关
2018-11-28 13:05:08
1941 次阅读
0 个评论
Fabricjs 作為了个已经出来了将近 10 年的 library (from 2008),也就是 ie 还盛行的年代,经歷 web 前端技术改变的考验,到 2018 还是不停在更新著。
既然在十年前就能使用这个 Library 了,过了十年硬体设备更强大的情况下,跑起来效能绝对不是问题,或许是因為 Fabricjs 原本定位就不再做出很炫很复杂的动画效果,而是在於和使用者的互动上。
2.0.0 版本之后,图片的滤镜就能够使用 WEBGL 来做渲染,对於图片滤镜的操作效能也是一大提升。
不过可惜的是绘製图形还不支援 WEBGL 比较没办法及时刷新更多的图形做粒子动画。
效能调校
来看看如何调整 Fabricjs 的运作效能。
大量图形绘製
一般使用 Fabricjs 来绘製一些简单图片和 2D 形状是没有甚麼问题的。
参考 fabricjs demo - particles 绘製一千颗粒子
以及参考官方 demo 做的 10000 颗粒子 codepen
renderOnAddRemove 做大量新增/删除
当我们在做大量新增或删除时,并不想要每次新增一个图形就自动重新刷新一次画布,所以可以将 canvas.renderOnAddRemove 设為 false 但是在大量 canvas.add() 之后,需要做一次 canvas.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),操作起来都是顺畅的。
既然在十年前就能使用这个 Library 了,过了十年硬体设备更强大的情况下,跑起来效能绝对不是问题,或许是因為 Fabricjs 原本定位就不再做出很炫很复杂的动画效果,而是在於和使用者的互动上。
2.0.0 版本之后,图片的滤镜就能够使用 WEBGL 来做渲染,对於图片滤镜的操作效能也是一大提升。
不过可惜的是绘製图形还不支援 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