大屏监控页面卡顿,如何优化 Canvas 渲染性能?
我们团队最近在做数据可视化大屏,用的是原生 Canvas 绘制图表和动态元素。但页面运行一段时间后明显卡顿,FPS 掉到 20 以下,尤其是在 Chrome 上。我试过用 requestAnimationFrame 控制绘制频率,也做了简单的脏矩形检测,但效果不明显。
有没有人遇到过类似问题?是不是应该改用 WebGL(比如 Three.js)?或者 Canvas 本身有哪些容易被忽略的性能陷阱?比如频繁创建对象、未清理路径之类的?
这是目前简化后的绘制逻辑:
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制多个动态折线图
data.forEach(line => {
ctx.beginPath();
line.points.forEach((p, i) => {
if (i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
});
requestAnimationFrame(draw);
}
draw();
1. 减少绘制区域。通用的做法是用
ctx.getImageData检查区域是否变化,只重绘变化部分。你现在是全量清除整个canvas,在数据量大时特别吃性能。2. 合并绘制操作。你现在的代码是每个折线图单独
beginPath和stroke,可以改成这样:3. 关闭canvas默认的平滑效果。加上
ctx.imageSmoothingEnabled = false;能省不少性能,特别是线条多的场景。4. 检查高频对象创建。比如你代码里的
line.points.forEach会产生临时函数对象,改成for循环会更好。5. 硬件加速。确保canvas的CSS宽高和属性宽高一致,别用CSS拉伸。加个
transform: translateZ(0)强制GPU加速。如果这些优化后还是卡,再考虑WebGL方案。其实Three.js学习成本不低,而且对于2D图表有点杀鸡用牛刀的感觉。我上次项目优化后,同样数据量下FPS从20提升到50+。