真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何優(yōu)化HTML5Canvas程序的性能

這篇文章主要介紹了如何優(yōu)化HTML5 Canvas程序的性能的相關(guān)知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇如何優(yōu)化HTML5 Canvas程序的性能文章都會有所收獲,下面我們一起來看看吧。

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比安寧網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式安寧網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋安寧地區(qū)。費用合理售后完善,十載實體公司更值得信賴。

【使用緩存】

使用緩存也就是用離屏canvas進行預(yù)渲染了,原理很簡單,就是先繪制到一個離屏canvas中,然后再通過drawImage把離屏canvas畫到主canvas中??赡芸吹竭@很多人就會誤解,這不是寫游戲里面用的很多的雙緩沖機制么?

其實不然,雙緩沖機制是游戲編程中為了防止畫面閃爍,因此會有一個顯示在用戶面前的畫布以及一個后臺畫布,進行繪制時會先將畫面內(nèi)容繪制到后臺畫布中,再將后臺畫布里的數(shù)據(jù)繪制到前臺畫布中。這就是雙緩沖,但是canvas中是沒有雙緩沖的,因為現(xiàn)代瀏覽器基本上都是內(nèi)置了雙緩沖機制。所以,使用離屏canvas并不是雙緩沖,而是把離屏canvas當成一個緩存區(qū)。把需要重復(fù)繪制的畫面數(shù)據(jù)進行緩存起來,減少調(diào)用canvas的API的消耗。

眾所周知,調(diào)用canvas的API很消耗性能,所以,當我們要繪制一些重復(fù)的畫面數(shù)據(jù)時,妥善利用離屏canvas對性能方面有很大的提升,可以看下下面的DEMO

1 、 沒使用緩存   

2、  使用了緩存但是沒有設(shè)置離屏canvas的寬高  

      3 、 使用了緩存但是沒有設(shè)置離屏canvas的寬高  

4 、 使用了緩存且設(shè)置了離屏canvas的寬高

可以看到上面的DEMO的性能不一樣,下面分析一下原因:為了實現(xiàn)每個圈的樣式,所以繪制圈圈時我用了循環(huán)繪制,如果沒用啟用緩存,當頁面的圈圈數(shù)量達到一定時,動畫每一幀就要大量調(diào)用canvas的API,要進行大量的計算,這樣再好的瀏覽器也會被拖垮啦。

XML/HTML Code復(fù)制內(nèi)容到剪貼板

ctx.save();   

                        var j=0;   

                        ctx.lineWidth = borderWidth;   

                        for(var i=1;i

                            ctx.beginPath();   

                            ctx.strokeStyle = this.color[j];   

                            ctx.arc(this.x , this.y , i , 0 , 2*Math.PI);   

                            ctx.stroke();   

                            j++;   

                        }   

                        ctx.restore();  

所以,我的方法很簡單,每個圈圈對象里面給他一個離屏canvas作緩存區(qū)。

除了創(chuàng)建離屏canvas作為緩存之外,下面的代碼中有一點很關(guān)鍵,就是要設(shè)置離屏canvas的寬度和高度,canvas生成后的默認大小是300X150;對于我的代碼中每個緩存起來圈圈對象半徑最大也就不超過80,所以300X150的大小明顯會造成很多空白區(qū)域,會造成資源浪費,所以就要設(shè)置一下離屏canvas的寬度和高度,讓它跟緩存起來的元素大小一致,這樣也有利于提高動畫性能。上面的四個demo很明顯的顯示出了性能差距,如果沒有設(shè)置寬高,當頁面超過400個圈圈對象時就會卡的不行了,而設(shè)置了寬高1000個圈圈對象也不覺得卡。

XML/HTML Code復(fù)制內(nèi)容到剪貼板

var ball = function(x , y , vx , vy , useCache){   

                this.x = x;   

                this.y = y;   

                this.vx = vx;   

                this.vy = vy;   

                this.r = getZ(getRandom(20,40));   

                this.color = [];   

                this.cacheCanvas = document.createElement("canvas");   

                thisthis.cacheCtx = this.cacheCanvas.getContext("2d");   

                this.cacheCanvas.width = 2*this.r;   

                this.cacheCanvas.height = 2*this.r;   

                var num = getZ(this.r/borderWidth);   

                for(var j=0;j

                    this.color.push("rgba("+getZ(getRandom(0,255))+","+getZ(getRandom(0,255))+","+getZ(getRandom(0,255))+",1)");   

                }   

                this.useCache = useCache;   

                if(useCache){   

                    this.cache();   

                }   

            }  

當我實例化圈圈對象時,直接調(diào)用緩存方法,把復(fù)雜的圈圈直接畫到圈圈對象的離屏canvas中保存起來。

XML/HTML Code復(fù)制內(nèi)容到剪貼板

cache:function(){   

                    this.cacheCtx.save();   

                    var j=0;   

                    this.cacheCtx.lineWidth = borderWidth;   

                    for(var i=1;i

                        this.cacheCtx.beginPath();   

                        thisthis.cacheCtx.strokeStyle = this.color[j];   

                        this.cacheCtx.arc(this.r , this.r , i , 0 , 2*Math.PI);   

                        this.cacheCtx.stroke();   

                        j++;   

                    }   

                    this.cacheCtx.restore();   

                }  

然后在接下來的動畫中,我只需要把圈圈對象的離屏canvas畫到主canvas中,這樣,每一幀調(diào)用的canvasAPI就只有這么一句話:

XML/HTML Code復(fù)制內(nèi)容到剪貼板

ctx.drawImage(this.cacheCanvas , this.x-this.r , this.y-this.r);  

跟之前的for循環(huán)繪制比起來,實在是快太多了。所以當需要重復(fù)繪制矢量圖的時候或者繪制多個圖片的時候,我們都可以合理利用離屏canvas來預(yù)先把畫面數(shù)據(jù)緩存起來,在接下來的每一幀中就能減少很多沒必要的消耗性能的操作。

下面貼出1000個圈圈對象流暢版代碼:

XML/HTML Code復(fù)制內(nèi)容到剪貼板

  

  

  

      

      

    測試  

  

  

   

  

        瀏覽器不支持canvas  

       

1000個圈圈對象也不卡
  

   

  

      

  

  

離屏canvas還有一個注意事項,如果你做的效果是會將對象不停地創(chuàng)建和銷毀,請慎重使用離屏canvas,至少不要像我上面寫的那樣給每個對象的屬性綁定離屏canvas。

因為如果這樣綁定,當對象被銷毀時,離屏canvas也會被銷毀,而大量的離屏canvas不停地被創(chuàng)建和銷毀,會導(dǎo)致canvas buffer耗費大量GPU資源,容易造成瀏覽器崩潰或者嚴重卡幀現(xiàn)象。解決辦法就是弄一個離屏canvas數(shù)組,預(yù)先裝進足夠數(shù)量的離屏canvas,僅將仍然存活的對象緩存起來,當對象被銷毀時,再解除緩存。這樣就不會導(dǎo)致離屏canvas被銷毀了。

【使用requestAnimationFrame】

這個就不具體解釋了,估計很多人都知道,這個才是做動畫的最佳循環(huán),而不是setTimeout或者setInterval。直接貼出兼容性寫法:

XML/HTML Code復(fù)制內(nèi)容到剪貼板

window.RAF = (function(){   

       return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60); };   

            })();   

【避免浮點運算】

雖然javascript提供了很方便的一些取整方法,像Math.floor,Math.ceil,parseInt,但是,國外友人做過測試,parseInt這個方法做了一些額外的工作(比如檢測數(shù)據(jù)是不是有效的數(shù)值,parseInt 甚至先將參數(shù)轉(zhuǎn)換成了字符串!),所以,直接用parseInt的話相對來說比較消耗性能,那怎樣取整呢,可以直接用老外寫的很巧妙的方法了:

JavaScript Code復(fù)制內(nèi)容到剪貼板

1.rounded = (0.5 + somenum) | 0;      

2.rounded = ~~ (0.5 + somenum);   3.rounded = (0.5 + somenum) << 0;      

【盡量減少canvasAPI的調(diào)用】

作粒子效果時,盡量少使用圓,最好使用方形,因為粒子太小,所以方形看上去也跟圓差不多。至于原因,很容易理解,我們畫一個圓需要三個步驟:先beginPath,然后用arc畫弧,再用fill進行填充才能產(chǎn)生一個圓。但是畫方形,只需要一個fillRect就可以了。雖然只是差了兩個調(diào)用,當粒子對象數(shù)量達到一定時,這性能差距就會顯示出來了。

還有一些其他注意事項,我就不一一列舉了,因為谷歌上一搜也挺多的。我這也算是一個給自己做下記錄,主要是記錄緩存的用法。想要提升canvas的性能最主要的還是得注意代碼的結(jié)構(gòu),減少不必要的API調(diào)用,在每一幀中減少復(fù)雜的運算或者把復(fù)雜運算由每一幀算一次改成數(shù)幀算一次。同時,上面所述的緩存用法,我因為貪圖方便,所以是每個對象一個離屏canvas,其實離屏canvas也不能用的太泛濫,如果用太多離屏canvas也會有性能問題,請盡量合理利用離屏canvas。

關(guān)于“如何優(yōu)化HTML5 Canvas程序的性能”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“如何優(yōu)化HTML5 Canvas程序的性能”知識都有一定的了解,大家如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


文章名稱:如何優(yōu)化HTML5Canvas程序的性能
URL地址:http://weahome.cn/article/pjheii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部