性能与可观测
SVG 慢,通常不是「矢量比 Canvas 慢」,而是 节点数 × 样式 × 滤镜离屏 打在主线程的 layout / paint 上。保留模式的代价是:每个 path 都是活对象。先测,再虚拟化或合并,最后才说换 Canvas。
文档清单
| 文档 | 解决的问题 |
|---|---|
| DOM 节点成本与虚拟化 | 几千 path 的 layout/paint;按视口挂载;何时改 Canvas |
| 滤镜合成层与重绘 | filter / mask / 组 opacity 离屏;缩放发糊;怎么测 |
测量原则
Chrome Performance 看 Main 上的 Recalculate Style / Layout / Paint,Layers 看离屏层。console.time 只能包到 JS;滤镜光栅在渲染进程里。不要用「我觉得 60fps」给几千节点过关。
相机仍然改 viewBox,见 01。CSS scale 整棵树会连滤镜缓冲一起放大,又糊又贵。will-change 同样可能把节点烘焙成位图,见 04。
成本分层
- DOM 基数: 可见独立节点数。静态底图合并
d;动态对象按视口remove。 - 样式与命中: 每节点事件、
marker、复杂选择器。不可点的底图pointer-events: none。 - 离屏: 组
opacity/filter/mask。装饰能烘焙就不要实时 blur。 - 换表面: 粒子、笔刷、每帧全量 morph → 选型。
vector-effect: non-scaling-stroke 只省「每帧改线宽」,不省节点数。
适用 / 不适用
| 适用 | 不适用 |
|---|---|
| 节点可命名、可点、数量可裁剪的图 | 粒子、笔刷、每帧全量 morph |
| 静态底图合并成少量 path | 给每个数据点挂一份 feGaussianBlur |
| 相机平移时卸载视口外节点 | 用 display: none 当虚拟化,文档仍膨胀 |
失败形态
| 症状 | 原因 |
|---|---|
| 一平移就掉帧 | 全图节点都在树上,没有视口裁剪 |
| 缩放后发光发糊 | 滤镜被光栅在旧尺寸 |
| 「优化 CSS」无效 | 成本在节点数和离屏,不在选择器名字 |
权威资料
核对日期:2026-08-26