iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 28
2
Modern Web

Fabricjs 筆記系列 第 28

Day 28 - 談談效能相關

  • 分享至 

  • xImage
  •  

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),操作起來都是順暢的。

參考連結


上一篇
Day 27 - 使用插件客製控制項
下一篇
Day 29 - Fabricjs 物件填充背景 Pattern
系列文
Fabricjs 筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言