SVG是DOM元素,Canvas是像素画布:SVG图形可交互、缩放无损、支持SEO和矢量导出,适合静态或需单元素操作的场景;Canvas帧率稳定、适合高频重绘与大数据量动态渲染,但需手动处理交互与响应式。

SVG 是 DOM 元素,Canvas 是像素画布
这是最根本的区别:SVG 中每个 、 都是真实存在的 DOM 节点,能被 document.querySelector 拿到,能绑 click 事件,能用 CSS 控制 fill 或 transform;Canvas 里画完就“消失”了——ctx.fillRect(10, 10, 100, 100) 只是在画布上填了一块像素,之后它不再有身份,也不能单独选中或响应鼠标悬停。
- 误以为 Canvas 图形能像 SVG 一样直接加
onclick?不行,得自己算坐标、做碰撞检测 - 想让图标随
font-size缩放还保持清晰?选 SVG,Canvas 需手动监听window.devicePixelRatio并重设canvas.width/height - 用 React/Vue 渲染大量图表项?SVG 天然支持组件化(比如封装一个
),Canvas 得自己管理整个渲染生命周期
缩放失真?Canvas 会糊,SVG 不会
SVG 是靠数学公式描述图形的(比如一个圆是 “圆心在 (50,50),半径为 30”),所以放大 10 倍还是光滑曲线;Canvas 是把图形“拍成照片”,存成一串像素值,放大后就是马赛克。
- 做响应式仪表盘,需要适配手机+4K 屏?SVG 自动撑满容器且无损;Canvas 必须监听
resize,重新设置canvas.width和canvas.height,再重绘全部内容 - 导出高清图?SVG 直接
outerHTML保存为 .svg 文件,或转成 PDF;Canvas 得调toDataURL('image/png'),但分辨率受限于当前画布尺寸 - 打印网页时图标模糊?Canvas 输出是位图,打印机 DPI 高时尤其明显;SVG 打印引擎直接按矢量重绘,原生锐利
性能瓶颈在哪?DOM 节点多选 SVG,帧率高选 Canvas
SVG 性能拐点在 DOM 节点数:画 200 个 没问题,画 5000 个就会卡顿(浏览器要维护 5000 个对象);Canvas 帧率稳定,哪怕每秒重绘 60 次,只要逻辑不卡 CPU,画面就流畅。
- 实时股票 K 线图(每秒更新数百根蜡烛)?Canvas 更稳;静态财报饼图(固定 5–10 个扇形)?SVG 更轻、更易 SEO 和可访问性
- 地图应用(如缩放拖拽)?Google Maps 早期用 SVG,后来核心图层全切 Canvas;但图钉、标注等 UI 层仍用 SVG——混合用才是常态
- 用 D3.js?它默认输出 SVG,但大数据量时得手动切换到 Canvas 渲染器(如
d3fc或自定义context绘制)
该选哪个?看这三件事
不用纠结理论,直接问自己:
立即学习“前端免费学习笔记(深入)”;
- 图形是否需要被用户点击/悬停/拖拽单个元素?→ 选 SVG(
包裹 +addEventListener直接可用) - 是否每秒重绘 >30 次,或图形数量 >1000 且持续变化?→ 选 Canvas(游戏、粒子动画、实时波形)
- 是否要支持屏幕阅读器、SEO 抓取、或允许用户右键“另存为”矢量图?→ SVG 原生支持,Canvas 需额外写
aria-label和降级图片
真正复杂的项目往往不是二选一,而是 SVG 画 UI 层(按钮、图例、文字),Canvas 画数据层(散点、热力、轨迹)——关键不是“哪个更好”,而是“哪部分该用哪个”。











