SVG 的性能优化对于提升网页加载速度和用户体验至关重要。以下是 SVG 性能优化的详细策略:
1. 文件大小优化
移除不必要的代码:
bash# 使用 SVGO 优化 SVG npx svgo input.svg -o output.svg # 批量优化 npx svgo -f ./icons -o ./optimized # 配置优化选项 npx svgo --config svgo.config.js input.svg -o output.svg
SVGO 配置示例:
javascript// svgo.config.js module.exports = { plugins: [ 'removeDoctype', 'removeXMLProcInst', 'removeComments', 'removeMetadata', 'removeUselessDefs', 'cleanupIDs', 'minifyStyles', 'convertPathData', 'mergePaths', 'removeUnusedNS', 'sortDefsChildren', 'removeEmptyAttrs', 'removeEmptyContainers', 'cleanupNumericValues', 'convertColors', 'removeUnknownsAndDefaults' ] };
2. 路径优化
简化路径命令:
svg<!-- 优化前 --> <path d="M 10.123456 20.654321 L 30.987654 40.321098" /> <!-- 优化后 --> <path d="M10.12 20.65L30.99 40.32" />
使用相对坐标:
svg<!-- 使用绝对坐标 --> <path d="M 10 10 L 20 10 L 20 20 L 10 20 Z" /> <!-- 使用相对坐标(更简洁)--> <path d="M10 10h10v10h-10z" />
合并路径:
svg<!-- 优化前 --> <rect x="10" y="10" width="50" height="50" fill="blue" /> <rect x="70" y="10" width="50" height="50" fill="blue" /> <!-- 优化后(使用 path)--> <path d="M10 10h50v50H10z M70 10h50v50H70z" fill="blue" />
3. 渲染性能优化
减少元素数量:
svg<!-- 优化前:多个独立元素 --> <circle cx="10" cy="10" r="5" fill="blue" /> <circle cx="20" cy="10" r="5" fill="blue" /> <circle cx="30" cy="10" r="5" fill="blue" /> <!-- 优化后:使用 group --> <g fill="blue"> <circle cx="10" cy="10" r="5" /> <circle cx="20" cy="10" r="5" /> <circle cx="30" cy="10" r="5" /> </g>
使用 CSS 代替 SVG 属性:
svg<!-- 优化前 --> <circle cx="50" cy="50" r="40" fill="blue" stroke="red" stroke-width="2" /> <!-- 优化后:使用 CSS --> <style> .circle { fill: blue; stroke: red; stroke-width: 2px; } </style> <circle class="circle" cx="50" cy="50" r="40" />
4. 动画性能优化
优先使用 CSS 动画:
css/* CSS 动画(GPU 加速)*/ .animated { animation: rotate 2s linear infinite; transform-origin: center; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
避免动画 width/height:
css/* 优化前:动画 width/height(性能差)*/ .bad { animation: scale 1s ease; } @keyframes scale { from { width: 50px; height: 50px; } to { width: 100px; height: 100px; } } /* 优化后:动画 transform(性能好)*/ .good { animation: scale 1s ease; } @keyframes scale { from { transform: scale(1); } to { transform: scale(2); } }
5. 滤镜性能优化
避免过度使用滤镜:
svg<!-- 避免复杂的滤镜链 --> <filter id="complex"> <feGaussianBlur stdDeviation="5" /> <feOffset dx="5" dy="5" /> <feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0" /> <feMerge> <feMergeNode in="SourceGraphic" /> <feMergeNode /> </feMerge> </filter> <!-- 简化滤镜或使用 CSS --> <style> .shadow { filter: drop-shadow(3px 3px 3px rgba(0,0,0,0.3)); } </style>
6. 加载优化
内联关键 SVG:
html<!-- 首屏关键 SVG 内联 --> <header> <svg viewBox="0 0 24 24" width="24" height="24"> <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" /> </svg> </header> <!-- 非关键 SVG 延迟加载 --> <img src="non-critical.svg" loading="lazy" alt="Non-critical" />
使用 SVG Sprite:
html<!-- 合并多个图标到一个文件 --> <svg style="display: none;"> <symbol id="icon1" viewBox="0 0 24 24">...</symbol> <symbol id="icon2" viewBox="0 0 24 24">...</symbol> <symbol id="icon3" viewBox="0 0 24 24">...</symbol> </svg> <!-- 使用图标 --> <svg><use href="#icon1" /></svg> <svg><use href="#icon2" /></svg>
7. 压缩和缓存
服务器配置:
nginx# Nginx 配置 location ~* \.(svg)$ { gzip on; gzip_vary on; gzip_min_length 1000; gzip_types image/svg+xml; expires 1y; add_header Cache-Control "public, immutable"; }
8. 监控和测试
性能测试工具:
- Lighthouse:测试整体性能
- WebPageTest:分析加载性能
- Chrome DevTools:监控渲染性能
最佳实践:
- 定期使用 SVGO 优化 SVG 文件
- 优先使用 CSS 动画
- 减少元素数量和复杂度
- 合理使用滤镜和渐变
- 内联关键 SVG,延迟加载其他
- 启用 gzip 压缩
- 设置适当的缓存策略
- 监控性能指标