好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

你必须知道的10个提高Canvas性能技巧

你还在抱怨自己写的canvas demo徘徊在10帧以下吗?你还在烦恼打开自己写的应用就听见CUP风扇转吗?你正在写一个javascript Canvas库吗?那么下面九点就是你必须知道的! 一.预渲染 错误代码: var canvas = document.getElementById( "myCanvas" ); var cont

你还在抱怨自己写的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   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   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   2   ? COLOR1 : COLOR2);
          context.fillRect(i * GAP,   0  , GAP,   480  );
      } 
  

正确代码:

       context.fillStyle = COLOR1;
        for   (  var   i =   0  ; i   2  ; i++) {
          context.fillRect((i *   2  ) * GAP,   0  , GAP,   480  );
      }
      context.fillStyle = COLOR2;
        for   (  var   i =   0  ; i   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  ;
  

九.使用requestAnimationFrame制作游戏或动画

( function () {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for ( var x = 0; x window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}

if (!window.requestAnimationFrame)
window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout( function () { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};

if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
} ());

十.其他

与渲染无关的计算交给worker

复杂的计算交给引擎(自己写,或者用开源的),比如3D、物理

缓存load好的图片,canvas上画canvas,而不是画image

同步

本文已同步更新至:

HTML5实验室【目录】: http://www.cnblogs.com/iamzhanglei/archive/2011/11/06/2237870.html

查看更多关于你必须知道的10个提高Canvas性能技巧的详细内容...

  阅读:36次