SVG 在移动端的应用需要特别注意性能、兼容性和用户体验。以下是 SVG 在移动端开发的最佳实践:
1. 响应式设计
使用 viewBox 实现响应式:
svg<svg viewBox="0 0 100 100" width="100%" height="auto"> <circle cx="50" cy="50" r="40" fill="blue" /> </svg>
使用媒体查询调整 SVG:
css/* 小屏幕 */ @media (max-width: 768px) { .mobile-svg { width: 100%; height: auto; } } /* 大屏幕 */ @media (min-width: 769px) { .mobile-svg { width: 50%; height: auto; } }
2. 触摸事件支持
添加触摸事件:
javascriptconst svg = document.querySelector('svg'); // 触摸开始 svg.addEventListener('touchstart', function(event) { event.preventDefault(); const touch = event.touches[0]; const point = svg.createSVGPoint(); point.x = touch.clientX; point.y = touch.clientY; const svgPoint = point.matrixTransform(svg.getScreenCTM().inverse()); console.log('Touch start:', svgPoint); }); // 触摸移动 svg.addEventListener('touchmove', function(event) { event.preventDefault(); const touch = event.touches[0]; // 处理触摸移动 }); // 触摸结束 svg.addEventListener('touchend', function(event) { event.preventDefault(); // 处理触摸结束 });
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 动画代替 SMIL:
css/* CSS 动画(性能更好)*/ .mobile-animated { animation: pulse 1s ease-in-out infinite; } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } }
4. 移动端特定优化
优化触摸目标大小:
svg<svg width="44" height="44" viewBox="0 0 24 24"> <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" fill="currentColor" /> </svg>
使用合适的字体大小:
svg<svg width="200" height="100" viewBox="0 0 200 100"> <text x="100" y="50" font-size="16" text-anchor="middle"> 移动端文本 </text> </svg>
5. 电池优化
减少动画复杂度:
css/* 简单的动画(省电)*/ .simple-anim { animation: fade 0.3s ease; } @keyframes fade { from { opacity: 0; } to { opacity: 1; } } /* 避免复杂的动画(耗电)*/ .complex-anim { /* 避免在移动端使用 */ }
使用 prefers-reduced-motion:
css@media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }
6. 网络优化
延迟加载非关键 SVG:
html<!-- 关键 SVG 立即加载 --> <svg class="critical" viewBox="0 0 24 24"> <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" /> </svg> <!-- 非关键 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> </svg> <!-- 使用图标 --> <svg><use href="#icon1" /></svg>
7. 兼容性处理
检测 SVG 支持:
javascriptfunction supportsSVG() { return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; } if (!supportsSVG()) { // 回退到 PNG document.querySelector('.svg-icon').src = 'icon.png'; }
提供回退方案:
html<picture> <source type="image/svg+xml" srcset="icon.svg" /> <img src="icon.png" alt="Icon" /> </picture>
8. 可访问性
添加适当的 ARIA 属性:
svg<svg role="img" aria-labelledby="svg-title svg-desc" tabindex="0"> <title id="svg-title">图标</title> <desc id="svg-desc">点击打开菜单</desc> <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" /> </svg>
支持屏幕阅读器:
javascriptconst svg = document.querySelector('svg'); svg.setAttribute('role', 'img'); svg.setAttribute('aria-label', '搜索图标');
9. 调试和测试
使用 Chrome DevTools 调试:
- 检查渲染性能
- 监控内存使用
- 测试触摸事件
在真实设备上测试:
- iOS Safari
- Android Chrome
- 各种屏幕尺寸
- 不同网络条件
最佳实践:
- 始终使用 viewBox 实现响应式
- 优化触摸目标大小(至少 44x44px)
- 减少动画复杂度以节省电池
- 延迟加载非关键 SVG
- 提供适当的回退方案
- 添加可访问性支持
- 在真实设备上测试
- 监控性能指标