SVG最適化とアイコン配信戦略(SVGO・シンボルスプライト・CSS変数)
SVGは拡大縮小に強く、配色やアニメも自在。ただし未最適化のSVGはDOMが重く、 レンダリングコストやバンドル肥大化の原因になります。本稿は、SVGOの実務設定と配信方式の選び方(inline/sprite/外部)を軸に、テーマ切替・アクセシビリティ・キャッシュ戦略まで整理します。
要点(TL;DR)
- SVGO必須:メタ削除・小数精度・重複統合でサイズ/DOM削減。
- 配信は用途で出し分け:inline=1個物/動的色、sprite=多数アイコン、外部=キャッシュ重視。
- CSS変数でテーマ対応(
currentColor
と相性良)。 - アクセシビリティ:意味のあるアイコンはラベル必須、装飾は
aria-hidden
。
1. SVGOの実務設定
// svgo.config.js(例) module.exports = { multipass: true, plugins: [ "removeDoctype", "removeXMLProcInst", "removeComments", "removeMetadata", "removeEditorsNSData", { name: "cleanupNumericValues", params: { floatPrecision: 3 } }, { name: "convertPathData", params: { floatPrecision: 3 } }, { name: "removeAttrs", params: { attrs: "(data-name|id|class)" } }, { name: "removeDimensions" }, // width/height削除(CSSで制御) ], };
可逆性を保つため、差分確認は必ず行いましょう(ビジュアル比較は QAプレイブック)。
2. 配信方式の選び方
A. inline(1個物・動的色)
<svg width="20" height="20" aria-hidden="true" focusable="false"> <path d="..." fill="currentColor" /> </svg>
- メリット:スタイル自由(CSS変数/アニメ)、HTTP往復ゼロ。
- デメリット:同じアイコンを多用すると重複しがち。
B. シンボルスプライト(多数アイコン)
<!-- sprite.svg --> <svg xmlns="http://www.w3.org/2000/svg" style="display:none"> <symbol id="icon-search" viewBox="0 0 24 24"><path d="..." /></symbol> <symbol id="icon-close" viewBox="0 0 24 24"><path d="..." /></symbol> </svg> <!-- 使用側 --> <svg width="20" height="20" aria-hidden="true"><use href="/sprite.svg#icon-search" /></svg>
- メリット:キャッシュ効く、重複ゼロ。
- デメリット:外部参照はCORS/埋め込み制約に注意(同一オリジン推奨)。
C. 外部読み込み(重い図版や再利用)
<img src="/img/diagram.svg" alt="仕組み図" width="640" height="360" />
図版は <img>
でOK。寸法の明示でCLSを防ぎます(詳細は CLSゼロ設計)。
3. テーマ切替とアクセシビリティ
/* CSS変数で配色 */ :root { --icon: #0a0a0a; } @media (prefers-color-scheme: dark) { :root { --icon: #fafafa; } } .icon { color: var(--icon); }
<!-- 装飾アイコン --> <svg class="icon" width="16" height="16" aria-hidden="true"><path fill="currentColor" d="..."/></svg> <!-- 意味のあるアイコン(ラベル必須) --> <button aria-label="検索"> <svg width="16" height="16" role="img" aria-labelledby="t1"><title id="t1">検索</title><path d="..."/></svg> </button>
4. 公開前チェック(8項目)
- SVGOで最小化(目視差分OK)。
- 用途に応じてinline/sprite/外部を選定。
- 意味のあるアイコンにラベル(装飾は
aria-hidden
)。 - テーマ切替で色が破綻しない(
currentColor
活用)。 - CLSゼロ:寸法明示 or CSSサイズ制御。
- 重い図版は遅延/分割読み込み。
- キャッシュ戦略(spriteは長期+指紋)。
- QAでビジュアル差分なし( QAプレイブック)。
5. まとめ:SVGは“賢く軽く”使う
SVGは適材適所で圧倒的に強力です。SVGOで可逆に絞る→配信方式を分ける→CSS変数とA11yで仕上げる。この順番を守れば、表示品質とパフォーマンスを両立できます。