DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> Canvas性能技巧:必須知道的Canvas性能技巧
Canvas性能技巧:必須知道的Canvas性能技巧
編輯:關於JavaScript     

你還在抱怨自己寫的canvas demo徘徊在10幀以下嗎?你還在煩惱打開自己寫的應用就聽見CUP風扇轉嗎?你正在寫一個javascript Canvas庫嗎?那麼下面九點就是你必須知道的!

一.預渲染
錯誤代碼:

      var canvas = document.getElementById("myCanvas");
      var context = this.canvas.getContext('2d');
      var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              drawMario(context);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
正確代碼:

      var canvas = document.getElementById("myCanvas");
      var context = this.canvas.getContext('2d');
      var m_canvas = document.createElement('canvas');
      m_canvas.width = 64;
      m_canvas.height = 64;
      var m_context = m_canvas.getContext('2d');
      drawMario(m_context);
      var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              context.drawImage(m_canvas, 0, 0);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
這裡m_canvas的寬度和高度控制得越小越好。

二.盡量少調用canvasAPI
錯誤代碼:

  
    for (var i = 0; i < points.length - 1; i++) {
          var p1 = points[i];
          var p2 = points[i + 1];
          context.beginPath();
          context.moveTo(p1.x, p1.y);
          context.lineTo(p2.x, p2.y);
          context.stroke();
      }
正確代碼:

      context.beginPath();
      for (var i = 0; i < points.length - 1; i++) {
          var p1 = points[i];
          var p2 = points[i + 1];
          context.moveTo(p1.x, p1.y);
          context.lineTo(p2.x, p2.y);
      }
      context.stroke();
三.盡量少改變CANVAS狀態
錯誤代碼:

      for (var i = 0; i < STRIPES; i++) {
          context.fillStyle = (i % 2 ? COLOR1 : COLOR2);
          context.fillRect(i * GAP, 0, GAP, 480);
      }
正確代碼:

      context.fillStyle = COLOR1;
      for (var i = 0; i < STRIPES / 2; i++) {
          context.fillRect((i * 2) * GAP, 0, GAP, 480);
      }
      context.fillStyle = COLOR2;
      for (var i = 0; i < STRIPES / 2; i++) {
          context.fillRect((i * 2 + 1) * GAP, 0, GAP, 480);
      }
四.重新渲染的范圍盡量小
錯誤代碼:

  context.fillRect(0, 0, canvas.width, canvas.height);
正確代碼:

      context.fillRect(20, 20, 100, 100);
五.復雜場景使用多層畫布
 <canvas  width="600" height="400" style="position: absolute; z-index: 0">
</canvas>
<canvas  width="600" height="400" style="position: absolute; z-index: 1">
</canvas>
六.不要使用陰影
      context.shadowOffsetX = 5;
      context.shadowOffsetY = 5;
      context.shadowBlur = 4;
      context.shadowColor = 'rgba(255, 0, 0, 0.5)';
      context.fillRect(20, 20, 150, 100);
七.清除畫布
詳細性能差別:
http://simonsarris.com/blog/346-how-you-clear-your-canvas-matters
一般情況下:clearRect的性能優於fillRect優於canvas.width = canvas.width;

八.像素級別操作盡量用整數
幾種取整數的方法:

      rounded = (0.5 + somenum) | 0;
      rounded = ~ ~(0.5 + somenum);
      rounded = (0.5 + somenum) << 0;
九.使用Jscex制作動畫效果
     var drawAsync = eval(Jscex.compile("async", function () {
          while (true) {
              context.drawImage(m_canvas, 0, 0);
              $await(Jscex.Async.sleep(1000));
          }
      }))
      drawAsync().start();
十.其他
與渲染無關的計算交給worker

復雜的計算交給引擎(自己寫,或者用開源的),比如3D、物理

緩存load好的圖片,canvas上畫canvas,而不是畫image

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved