用 Canvas 优化粒子动画的性能实践
#Canvas#性能
背景
给网站做星空背景时,粒子动画在移动端出现了明显掉帧。本文记录完整的排查与优化过程。
问题定位
最初的实现每秒渲染大量粒子,每次 requestAnimationFrame 都做全量绘制。
// ❌ 每次都创建新对象,触发频繁 GC
function draw() {
particles.forEach((p) => {
ctx.fillStyle = `rgba(255,255,255,${Math.random()})`;
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fill();
});
}优化手段
降低粒子数量
移动端把粒子数从 150 降到 50,视觉上几乎无差别,绘制开销显著下降。
限制 devicePixelRatio
高分屏上 dpr 可达 3,绘制像素翻倍。把 dpr 上限设为 2 即可明显提速。
尊重偏好设置
// ✅ 尊重 prefers-reduced-motion,渲染静态星点
const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;结论
通过「降数量 + 限 dpr + 减动画」三步,移动端稳定在 50fps 以上。
| 优化项 | 效果 |
|---|---|
| 降低粒子数 | 绘制开销减半 |
| 限制 dpr | 高分屏提速明显 |
| 减动画 | 尊重用户偏好 |