01 · NOTES / WebGIS 开发
第 11 节 · 渲染器原理(SVG vs Canvas)
2026 年 9 月 1 日
第 11 节 · 渲染器原理(SVG vs Canvas)
📌 版本信息:Leaflet 1.9.4(2026-08-29 核对) 📚 来源:Leaflet Path 文档(renderer 选项) | 源码
src/layer/vector/Renderer.js / SVG.js / Canvas.js🎯 矢量要素到底怎么画到屏幕上?两种渲染器决定了性能上限与交互方式。
一、这一节的目标
- 理解 Renderer 抽象:Path 图层与渲染器解耦
- 精通 SVG 与 Canvas 渲染器的差异与选型(
preferCanvas) - 掌握渲染管线:投影 → 裁剪 → 绘制(与重绘时机)
- 建立矢量性能的量化直觉
二、Renderer 抽象:图层与"怎么画"解耦
// 每个 Path 图层(线/面/圆)都有 renderer 选项:
L.polygon(..., { renderer: L.canvas({ padding: 0.5 }) }) // 指定用 canvas 画这一个
// 或地图级全局默认(最常用):
const map = L.map('map', { preferCanvas: true }); // 本图所有矢量默认 Canvas 渲染
// 未指定时:默认 SVG 渲染器(每张图一个全局 SVG 实例)
两种渲染器的本质:SVG = 一个个 DOM 元素(<path>),Canvas = 一个 <canvas> 位图上重画。
三、SVG vs Canvas 全面对比
| 维度 | SVG 渲染器 | Canvas 渲染器 |
|---|---|---|
| DOM 结构 | 每要素一个 <path> 节点 |
单个 canvas,无逐要素节点 |
| 交互 | 原生:DOM 事件,hover/点击精细 | 手动命中检测(数学算点在不在图形里) |
| 样式 | CSS 可选(hover 变色写 CSS) | 只能 JS 重画 |
| 动画 | DOM 动画(CSS transition 可用) | 重画 |
| 性能 | 要素多时 DOM 撑爆(约 >500 个卡顿) | 大批量快(数千甚至上万可跑) |
| 视觉细节 | 抗锯齿好、打印友好 | 大量要素重画耗时 |
| 文本/复杂标记 | 与 DOM 生态相容 | 全靠手画 |
选型口诀:几十几百个要素要精细交互 → SVG(默认);上千个点/面要流畅 → preferCanvas: true;超大(万级)→ 聚合/虚拟化或换 deck.gl(模块 15)。
四、渲染管线与重绘时机
数据变化(addLayer/setStyle/地图平移缩放)
↓
Path._project():经纬度 → 像素坐标(用 CRS 的投影,模块 04 数学)
↓
裁剪(clip):视口外的线段/面片剔除(不画看不见的)
↓
Renderer._update():
SVG → 更新各 <path> 的 d 属性
Canvas → clearRect 全清 → 遍历可见要素逐个画
↓
浏览器渲染(SVG 进 DOM 树;Canvas 位图合成)
重绘触发时机:moveend 后(Canvas 默认 updateWhenIdle 风格:拖动中不重绘、停下重绘——updateWhenIdle: false 可改"边拖边画",更流畅但更耗);SVG 因 DOM 元素持续存在,拖动用 CSS transform 平移(不重画)。
💡 与第 15 节的呼应:deck.gl 之所以能扛十万级,就是把 Canvas 思路推到 WebGL(GPU 批量画)。渲染器的演进线:DOM(SVG) → 2D Canvas → WebGL——性能递增、交互复杂度也递增。
五、自测题
- renderer 选项的两种设置层级?
- SVG 渲染器的交互优势来自什么?
- Canvas 渲染器处理点击的原理?
- preferCanvas 后 bindTooltip 还有吗?
- 万级要素的方案排序?
参考答案
- 图层级 renderer 选项 / 地图级 preferCanvas 全局默认。
- 每要素一个
<path>DOM 节点,浏览器原生事件与 hover。 - 无 DOM——监听 canvas 事件后用几何算法做命中检测(点在多边形内等)。
- 有。Tooltip 由 Leaflet 统一管理(tooltipPane),与渲染器无关;但 Canvas 模式下部分逐要素 hover 细节不如 SVG 灵敏。
- 聚合(markercluster)→ preferCanvas+简化 → 虚拟化/分片 → 换 WebGL 方案(deck.gl/MapLibre)。
六、下一步
渲染原理在握 → 第 12 节:Vector 图层全参数——Polyline/Polygon/Circle 每个选项的意义。