选 SVG 还是 Canvas,关键看是否需操作单个图形和无限缩放不失真:SVG 是 DOM 元素,支持事件绑定、CSS 动画、无障碍与 SEO;Canvas 是像素画布,适合高频重绘、像素操作与游戏,但需手动处理交互与缩放适配。

选 SVG 还是 Canvas,关键看你要不要“操作单个图形”和“无限缩放不失真”。如果答案是肯定的,SVG 几乎总是更省力;如果要每秒重绘上千个对象、做像素级滤镜或游戏主循环,Canvas 是绕不开的。
SVG 是 DOM 元素,Canvas 是一块像素画布
SVG 中每个 <circle>、<path> 都是真实存在的 DOM 节点,可以用 document.querySelector('circle') 拿到,也能绑定 click 事件、加 hover 样式、用 CSS 动画控制 transform。Canvas 则只有一块 <canvas> 元素,所有绘制结果都变成像素堆在内存里,画完就“失联”——没有 getCircleById() 这种 API,想响应点击得自己算坐标、做碰撞检测。
常见错误现象:
- 把 SVG 当成纯图片用
<img src="icon.svg">,结果无法用 JS 控制颜色或加交互 - 在 Canvas 上画了 1000 个圆,却试图用
canvas.getElementById('dot-42')找某个圆(这根本不存在)
缩放与分辨率:SVG 天然清晰,Canvas 需手动适配
SVG 基于数学描述,viewBox 和 CSS width/height 分离,放大 10 倍依然锐利;Canvas 是位图,canvas.width 和 canvas.height 是实际像素数,直接设为 300×300 再用 CSS 拉到 600×600,就会模糊。必须按设备像素比(window.devicePixelRatio)手动缩放画布尺寸并调整绘图坐标。
立即学习“前端免费学习笔记(深入)”;
使用场景差异:
- 图标、UI 组件、响应式图表 → 优先 SVG,免去 DPR 适配负担
- 截图导出为 PNG/JPEG、需要抗锯齿控制的渲染 → Canvas 更可控(
ctx.imageSmoothingEnabled = false)
性能拐点:SVG 卡在 DOM 节点数,Canvas 卡在重绘频率
SVG 渲染慢不是因为“矢量”,而是浏览器要维护大量 DOM 节点。实测中,超过 5000 个 <circle> 就可能明显卡顿;Canvas 不管画多少个圆,只要不超帧率极限(如 60fps),CPU/GPU 负担稳定——但你要自己管理状态、清屏、重绘全部内容。
参数与影响:
- SVG 场景下,用
<use href="#template">复用定义可减少节点膨胀 - Canvas 场景下,避免每帧调用
ctx.clearRect()后全量重绘;对静态背景可用双缓冲,或只重绘变化区域 - 大量文本渲染?SVG 的
<text>支持 CSS 字体控制,Canvas 的fillText()易出现模糊且换行麻烦
可访问性与 SEO:SVG 可读,Canvas 需额外补救
SVG 元素能加 aria-label、title、role,屏幕阅读器可识别;Canvas 默认是“黑盒”,必须用 aria-hidden="true" 配合外置 <div role="img"> 描述,否则对无障碍用户不可用。搜索引擎也只索引 SVG 的标签结构(比如 <title>Sales Chart</title>),对 Canvas 内容完全无视。
容易被忽略的地方:
混合使用时,别让 Canvas 遮住 SVG 的交互层——z-index 或 pointer-events: none 得配好;还有,Canvas 导出图像后丢失所有语义,而 SVG 导出仍是可编辑矢量,这点在设计系统交付时特别关键。



















