Canvas 11
canvas的优化
性能提升的技巧
在离屏的canvas上预渲染相似的图形或重复的对象。
如果存在相同的绘制操作在每个动画帧上,我们可以考虑将其分流到屏幕的画布上。
myCanvas.offscreenCanvas = document.createElement("canvas");
myCanvas.offscreenCanvas.width = myCanvas.width;
myCanvas.offscreenCanvas.height = myCanvas.height;
myCanvas.getContext("2d").drawImage(myCanvas.offScreenCanvas, 0, 0);
myEntity.offscreenCanvas = document.createElement("canvas");
myEntity.offscreenCanvas.width = myEntity.width;
myEntity.offscreenCanvas.height = myEntity.height;
myEntity.offscreenContext = myEntity.offscreenCanvas.getContext("2d");
myEntity.render(myEntity.offscreenContext);
避免使用浮点数的像素,使用整数替代。
当我们绘制一个非整数的坐标点的对象时就会发生子像素渲染,但是会增加浏览器的额外运算。
不要使用drawImage进行图片的缩放
我们可以通过离屏画布预先加载渲染不同尺寸的图片,不使用drawImage中缩放
使用分层的画布在复杂的场景中
例如我们在应用中有一些需要频繁移动的元素,而其他一些元素需要保持相对不变。我们可以使用多个canvas元素进行部分分层渲染。
使用纯css添加大的背景图
使用css变换进行canvas画板的缩放
css transforms会使用GPU进行加速渲染页面,最好不要直接缩放画布,或者较小的画布按比例放大,而不是较大的画布按比例缩小。
var scaleX = window.innerWidth / canvas.width;
var scaleY = window.innerHeight / canvas.height;
var scaleToFit = Math.min(scaleX, scaleY);
var scaleToCover = Math.max(scaleX, scaleY);
stage.style.transformOrigin = "0 0"; //scale from top left
stage.style.transform = "scale(" + scaleToFit + ")";
关闭透明度
当我们的画布无需透明度,我们可以在获取上下文添加选项,帮助我们浏览器进行内部优化。
var ctx = canvas.getContext("2d", { alpha: false });
缩放高分辨率的显示器
当我们发现canvas画布内容在高分辨率的显示屏上显示模糊需要设置缩放一定的比例。
// Get the DPR and size of the canvas
const dpr = window.devicePixelRatio;
const rect = canvas.getBoundingClientRect();
1 // Set the "actual" size of the canvas
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
2 // Scale the context to ensure correct drawing operations
ctx.scale(dpr, dpr);
3 // Set the "drawn" size of the canvas
canvas.style.width = `${rect.width}px`;
canvas.style.height = `${rect.height}px`;
- 批量绘制操作,不是一根根折线绘制,而是一起绘制。
- 避免非必要的画布状态改变
- 避免使用shadowBlur属性扩大阴影
- 差异渲染
- 尽可能避免文本渲染
- 绘制动画时尽量使用window.requestAnimationFrame()
- 谨慎使用一些大型的物理库
写在最后
未完待续…
希望大家好好生活,健康快乐。