Canvas 与 SVG 的区别
面试速答(30 秒版 TL;DR)
- Canvas 是位图画布,偏“即时绘制(immediate mode)”;你用 JS 把像素画上去,浏览器不会替你保留图形对象结构。
- SVG 是矢量图形,偏“保留模式(retained mode)”;每个图形元素都是 DOM 节点,天然有结构、样式和事件。
- 典型选择:
- 高频重绘、粒子动画、游戏、图像处理:优先 Canvas
- 图标、流程图、地图、可缩放图形、需要 DOM 交互的图表:优先 SVG
- 一句话记忆:Canvas 擅长“画得快”,SVG 擅长“管得清”。
核心对比表
| 维度 | Canvas | SVG |
|---|---|---|
| 图形本质 | 位图 | 矢量 |
| 渲染模式 | 即时模式 | 保留模式 |
| 是否有 DOM 节点 | 没有,每次重画 | 有,每个图形可单独操作 |
| 缩放表现 | 放大会失真 | 天然不失真 |
| 事件绑定 | 需自己做命中检测或局部封装 | 可直接绑到元素 |
| 动画方式 | 重绘整块或局部 | 改属性、CSS、SMIL、JS |
| 适合场景 | 高频绘制、像素处理、游戏 | 图标、图表、结构化图形 |
心智模型:画板 vs 图形文档
你可以这样讲:
- Canvas 像 Photoshop 里的画布,落笔后更多关心“结果像素”。
- SVG 像 Figma / Illustrator 里的对象树,更关心“这个圆、这条线、这段路径”本身。
Canvas 的特点
1)更适合高频绘制
<canvas id="chart" width="600" height="300"></canvas>
const canvas = document.getElementById('chart')
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#2563eb'
ctx.fillRect(20, 20, 120, 60)
特点:
- 绘制 API 直接操作画布
- 适合动画循环里不断
clearRect + redraw - 做像素级处理更直接,比如图片压缩、截图、滤镜
2)缺点是“对象感弱”
画完一个矩形后,浏览器不会替你保留“这是第几个矩形”的 DOM 结构。后续如果想拖拽、选中、命中测试,往往要自己维护一份图形数据模型。
SVG 的特点
1)每个图形都是结构化节点
<svg width="240" height="120" viewBox="0 0 240 120">
<rect x="20" y="20" width="80" height="40" rx="8" fill="#2563eb" />
<circle cx="160" cy="40" r="24" fill="#f59e0b" />
<text x="20" y="95" font-size="16">前端图形</text>
</svg>
特点:
- DOM 可选中、可加类名、可单独绑定事件
- 放大不失真
- CSS 控制方便,适合图标、示意图、流程图
2)缺点是节点多时管理成本上升
如果页面里有成千上万个 SVG 元素,每个都在参与 DOM / 样式 / 布局 / 事件系统,性能压力会比 Canvas 更明显。
高频考点:为什么 Canvas 更适合游戏和粒子动画?
因为这类场景的核心诉求通常是:
- 每一帧都在变
- 元素数量很多
- 更关心重绘吞吐,而不是单个图形的 DOM 语义
典型循环:
function render() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
particles.forEach((item) => {
ctx.beginPath()
ctx.arc(item.x, item.y, item.r, 0, Math.PI * 2)
ctx.fill()
})
requestAnimationFrame(render)
}
render()
这类“整帧重画”的模式和 Canvas 很契合。
高频考点:为什么 SVG 更适合图标和流程图?
因为它有三个天然优势:
- 不失真:缩放、高清屏都稳
- 结构清晰:每个图形可独立控制
- 可访问性更好:可加
title、desc、ARIA 属性
这也是为什么很多图标库、流程图工具、拓扑图会优先选 SVG。
如何选型?
典型题 & 标准答法
Q1:Canvas 和 SVG 的本质区别是什么?
答法建议:
- Canvas 是位图画布,靠脚本直接绘制像素,偏即时模式。
- SVG 是矢量图形,每个形状都是结构化元素,偏保留模式。
Q2:什么时候选 Canvas,什么时候选 SVG?
答法建议:
- 高频动画、游戏、图像处理选 Canvas。
- 图标、流程图、图表、需要缩放不失真的场景选 SVG。
Q3:谁的性能更好?
答法建议:
- 不能脱离场景谈。
- 大量频繁重绘 通常 Canvas 更有优势。
- 图形数量不大但需要交互和结构管理 时,SVG 更省心。
常见追问
- SVG 能做动画吗?
- 可以,能用 CSS、JS 改属性;只是超大量、高频复杂动画未必比 Canvas 合适。
- Canvas 能加事件吗?
- 画布节点本身能加事件,但具体点中了哪个图形,通常要自己做命中检测。
- Canvas 一定会失真吗?
- 本质是位图,放大可能失真;但可以结合 DPR 提高绘制分辨率来缓解。
易错点 / 坑
- 把“Canvas 性能一定更高”当绝对结论。场景不同,瓶颈不同。
- 拿 SVG 做海量粒子动画,节点数一大就容易吃 DOM 成本。
- 拿 Canvas 做强交互编辑器却不维护图形模型,后期交互会很痛苦。
- 忽略高清屏 DPR,导致 Canvas 发虚。
速记要点(可背诵)
- Canvas:位图、即时模式、重绘强。
- SVG:矢量、保留模式、结构强。
- Canvas 擅长“画得快”,SVG 擅长“管得清”。
- 动画游戏偏 Canvas,图标图表偏 SVG。