Improving HTML5 Canvas Performance

提高Canvas渲染性能的几点总结

  • 预渲染到离屏画布

no pre-rendering:

1
2
3
4
5
// canvas, context are defined
function render() {
drawMario(context);
requestAnimationFrame(render);
}

pre-rendering:

1
2
3
4
5
6
7
8
9
10
var m_canvas = document.createElement('canvas');
m_canvas.width = 64;
m_canvas.height = 64;
var m_context = m_canvas.getContext(‘2d’);
drawMario(m_context);
function render() {
context.drawImage(m_canvas, 0, 0);
requestAnimationFrame(render);
}
  • 集中调用canvas
1
2
3
4
5
6
7
8
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();
}
1
2
3
4
5
6
7
8
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();
  • 避免不必要的画布状态改变
1
2
3
4
for (var i = 0; i < STRIPES; i++) {
context.fillStyle = (i % 2 ? COLOR1 : COLOR2);
context.fillRect(i * GAP, 0, GAP, 480);
}
1
2
3
4
5
6
7
8
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);
}
  • 仅渲染视窗部分
1
context.fillRect(0, 0, canvas.width, canvas.height);
1
context.fillRect(last.x, last.y, last.width, last.height);
  • 将多层画布用于复杂场景
1
2
3
4
<canvas id="bg" width="640" height="480" style="position: absolute; z-index: 0">
</canvas>
<canvas id="fg" width="640" height="480" style="position: absolute; z-index: 1">
</canvas>
  • 避免使用 shadowBlur 效果
1
2
3
4
5
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
//context.shadowBlur = 4;
context.shadowColor = 'rgba(255, 0, 0, 0.5)';
context.fillRect(20, 20, 150, 100);
  • 了解清空画布的各种方法
1
2
context.clearRect(0, 0, width, height);
canvas.width = canvas.width;
  • 避免使用浮点数坐标
1
2
3
4
rounded = (0.5 + somenum) | 0;
rounded = ~~ (0.5 + somenum);
// Finally, a left bitwise shift.
rounded = (0.5 + somenum) << 0;
  • 使用 requestAnimationFrame 优化你的动画
1
2
3
4
5
6
7
8
9
10
11
var x = 100;
var y = 100;
var lastRender = Date.now();
function render() {
var delta = Date.now() - lastRender;
x += delta;
y += delta;
context.fillRect(x, y, W, H);
requestAnimationFrame(render);
}
render();

参考链接:
https://www.html5rocks.com/en/tutorials/canvas/performance/