[程設雜筆] 增進canvas上動畫效能

最近在寫一個程式,需要在canvas上畫出大量的點點,而且是以動畫的形式呈現,所以當要畫的點多起來時,瀏覽器就會變得很當。htop了一下,發現瀏覽器繪圖吃太多CPU資源了。於是就研究一下,如何把CPU的使用率壓下去。

首先,之前寫前端的動畫時,我都會用setInterval或setTimeout,但是後來發現,我的動畫好像都會漏格,於是就研究了一下,發現只要把這兩個方法都換成requestAnimFrame即可。而各家瀏覽器在這方面的名稱都不一樣,所以要自己定義自己的方法。

[code language=”javascript”]
window.requestAnimFrame = (function(){
return window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla
window.oRequestAnimationFrame || //Opera
window.msRequestAnimationFrame || //IE
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();

drawAnim(){//畫動畫
.
.
.
.
window.requestAnimFrame(this.drawAnim.bind(this));
}

[/code]

此外,這個方法預設的fps是60,也就是每秒刷畫面60次。我的動畫來說,這樣吃的資源太多了,所以把fps下降到30,也就是一次畫,一次不畫,吃的CPU馬上顯著下降。

可是我覺得效能降的還不是很滿意,於是打開google chrome 按F12得到下面這個畫面,就可以開始測我們的網頁到底吃了多少CPU。
chrome-profile

本來的程式碼長下面這個樣子,也就是每畫一個點都beginpath(), fill(), closepath()一次。

[code language=”javascript”]
//point collection.draw()
this.draw=function(){
for(let i=0;i<this.points.length;i++){
points[i].draw();
}
};

//points.draw
this.draw=function(){
ctx.fillStyle=color;
ctx.beginPath();
ctx.arc(this.curPos.x,this.curPos.y,radius,0,Math.PI*2,true);
ctx.fill();
ctx.closePath();
};
[/code]

可是看了一下cpu profile,發現大部分的資源都花在fill這裡,於是就改了一下程式呼叫的先後。變成全部的點點都設好後,再一次fill(),也就是下面這樣。

[code language=”javascript”]
//point collection.draw()
this.draw=function(){
ctx.beginPath();
for(let i=0;i<this.points.length;i++)
this.points[i].draw();
ctx.fill();
ctx.closePath();
};
//points.draw
this.draw=function(){
ctx.fillStyle=color;
ctx.moveTo(this.curPos.x,this.curPos.y);
ctx.arc(this.curPos.x,this.curPos.y,radius,0,Math.PI*2,true);
};
[/code]

再看一下CPU的profile,馬上顯著的下降。如下圖

canvascpu1
優化前
canvascpu2
優化後

但是,在fill的時候,如果fillstyle有改變,就要先fill,然後再closepath,beginpath,否則會以最後設定的fillstyle為主。所以最好的狀況,就是把所有相同的fillstyle,全部都一次指定好,一次fill,就不用一直切換fillstyle,然後重複的執行最耗資源的fill()

參考資料:
http://blog.tonycube.com/2012/03/html5-canvas-6.html

https://msdn.microsoft.com/zh-tw/library/hh920765(v=vs.85).aspx

http://www.html5rocks.com/en/tutorials/canvas/performance/

關於我:

我是沒一村,專長和興趣是程式、主動投資、科技商業模式。可以參考我的書單和比較熱門的文章:

分享:

Leave a Reply