SVG 对比和最佳实践
1. SVG vs 其他图片格式
SVG vs PNG/JPEG
特性 | SVG | PNG | JPEG |
---|---|---|---|
文件类型 | 矢量图 | 位图 | 位图 |
缩放 | 无损放大 | 放大失真 | 放大失真 |
文件大小 | 取决于复杂度 | 取决于尺寸和颜色 | 较小 |
透明度 | 支持 | 支持 | 不支持 |
动画 | 支持 | 不支持 | 不支持 |
编辑性 | 可编程和修改 | 不可编辑 | 不可编辑 |
适用场景 | 图标、动画、交互 | 照片、复杂图像 | 照片、大图像 |
优势
-
可缩放性
- 在任何分辨率下都保持清晰
- 适应不同屏幕尺寸
- 无需准备多套图片资源
-
可编程性
- 可以通过 CSS 修改样式
- 支持 JavaScript 交互
- 可以动态生成和修改
-
可访问性
- 文本内容可被搜索引擎索引
- 支持屏幕阅读器
- 可以添加 ARIA 属性
劣势
-
性能考虑
- 复杂 SVG 渲染成本高
- 大量 SVG 元素会影响性能
- 文件大小可能超过位图
-
浏览器兼容
- 老版本浏览器支持有限
- 复杂动画可能有兼容性问题
- 不同浏览器渲染可能有差异
2. 使用建议
适合使用 SVG 的场景
// 1. 简单的图标
<svg viewBox="0 0 24 24">
<path d="M12 2L1 21h22L12 2z" />
</svg>
// 2. Logo
<svg width="100" height="40">
<text x="10" y="30" font-family="Arial">LOGO</text>
</svg>
// 3. 数据可视化
<svg width="200" height="100">
<rect x="10" y="10" width="20" height="80" />
<rect x="40" y="30" width="20" height="60" />
<rect x="70" y="40" width="20" height="50" />
</svg>
不适合使用 SVG 的场景
- 照片和复杂图像
- 大量重复的小图标
- 需要图片压缩的场景
3. 性能优化
1. 文件优化
// 优化前
<svg width="100" height="100">
<circle cx="50.0" cy="50.0" r="40.0" fill="#ff0000" />
</svg>
// 优化后
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
2. 加载优化
<!-- 内联关键 SVG -->
<svg>...</svg>
<!-- 非关键 SVG 使用 img 标签 -->
<img src="icon.svg" alt="icon" loading="lazy" />
<!-- 使用 symbol 复用 -->
<svg>
<symbol id="icon" viewBox="0 0 24 24">
<path d="M12 2L1 21h22L12 2z" />
</symbol>
</svg>
<svg><use href="#icon" /></svg>
3. 渲染优化
/* 使用 will-change 提示浏览器 */
.animated-svg {
will-change: transform;
}
/* 使用 CSS transform 代替 SVG transform */
.optimized-svg {
transform: translate(100px, 100px);
}
4. 最佳实践
1. 文件管理
// 组件化管理
const Icon = ({ name, ...props }) => {
const icons = {
arrow: <path d="M7 10l5 5 5-5" />,
close: <path d="M18 6L6 18M6 6l12 12" />
};
return (
<svg viewBox="0 0 24 24" {...props}>
{icons[name]}
</svg>
);
};
2. 可访问性
<svg role="img" aria-label="描述">
<title>图标标题</title>
<desc>详细描述</desc>
<!-- SVG 内容 -->
</svg>
3. 响应式设计
.responsive-svg {
width: 100%;
height: auto;
max-width: 600px;
}
@media (max-width: 768px) {
.responsive-svg {
max-width: 300px;
}
}
5. 常见问题
1. 文本处理
// 问题:文本可能在不同系统显示不一致
<svg>
<text>Hello</text>
</svg>
// 解决:转换为路径
<svg>
<path d="M..." />
</svg>
// 或使用 Web 字体
<svg>
<text font-family="'Google Sans', sans-serif">Hello</text>
</svg>
2. 移动端优化
// 使用 viewBox 而不是固定尺寸
<svg viewBox="0 0 24 24">
<!-- 内容 -->
</svg>
// 避免过于复杂的路径
// 使用简化的路径数据
<path d="M10 10h4v4h-4z" />