canvas适合高频重绘与动态元素(如仪表盘、粒子动画),svg适合结构化、需交互或缩放的矢量内容(如流程图、地图标注),二者应依是否需缩放、交互、矢量保真等实际需求选择。

Canvas 和 SVG 不是“谁更好”的问题,而是“哪个更合适”的判断。选错技术,后期重构成本远高于前期多花十分钟理清需求。
需要频繁重绘动态内容?选 Canvas
Canvas 本质是像素画布,适合每帧都变的场景。它不保存图形状态,靠 JavaScript 手动清屏、重画,反而让性能更可控。
- 实时仪表盘(温度曲线滚动、设备状态闪烁):每帧只调
clearRect()+lineTo()连线,不碰 DOM - 粒子动画、烟花、游戏主画布:用
Float32Array存位置/速度,JS 层轻量,GPU 友好 - 导出 PNG:直接调
toDataURL("image/png"),一步到位
要支持缩放、点击、样式控制?选 SVG
SVG 是 XML 标签组成的矢量图,每个 <circle></circle>、<path></path> 都是真实 DOM 节点,天然支持事件、CSS 和无障碍。
- 地图标注、流程图、图标系统:设
viewBox+width="100%",浏览器自动等比缩放,无损清晰 - 交互式图表(悬停高亮某条线、点击钻取):给
<polyline></polyline>直接绑onclick,不用自己算坐标 - 需右键另存为高清图或导出 PDF:SVG 原生支持,Canvas 得靠
canvg或服务端中转
分辨率适配很关键,但处理方式完全不同
Canvas 在 Retina 屏上模糊?不是 bug,是没适配设备像素比。SVG 则基本不用操心。
- Canvas 必须手动处理:
canvas.width = cssWidth * window.devicePixelRatio,绘图坐标也得同步放大 - SVG 只需写对
viewBox,再用 CSS 控制宽高,缩放由浏览器自动完成 - 常见错误:把
<img src="chart.svg">当图标用——这样无法改颜色、加事件,应内联或用<object></object>
数据量大时,性能拐点很现实
不是“越多越好”,而是“多少才开始卡”。这个阈值直接影响技术选型。
- Canvas:画 10000 个移动小球依然流畅,内存占用和元素数量无关
- SVG:超过 5000 个
<circle></circle>就可能触发重排重绘瓶颈,DOM 树膨胀明显 - 折中方案:混合使用——用 SVG 做静态底图(如地图轮廓),Canvas 渲染动态层(如实时轨迹点)











