開発者のためのSVG最適化:SVGO、ビルドパイプライン、CI/CD統合
開発者向けSVG最適化ガイド:SVGOの設定、webpack/Viteビルドパイプラインへの統合、CI/CDによる自動化、Core Web Vitalsへの影響を解説。

Founder of VectoSolve
Self-taught developer, founder and sole developer of VectoSolve since 2024. He builds the conversion engine and the cutting, embroidery and 3D printing exports.
How this article was made: drafted with AI assistance, then edited and fact-checked before publication. About the author
Key Takeaways
-
調整された
svgo.config.jsを使用したSVGOは、視覚的な劣化なしにSVGファイルサイズを60-85%削減します - パス簡素化(小数精度 + 冗長ノード)は最も効果の高い最適化です
-
過度な最適化はCSSアニメーションと
currentColorを壊します -- SVGO後は必ずテストしてください - Gzipでさらに70-80%削減。Brotliはその上に5-8%追加で圧縮します
- Intersection Observerによる遅延読み込みで、画面外のレンダリングコストを排除できます
- ビルドパイプライン統合(Vite、webpack、Next.js)により、最適化がチームにとって透過的になります
SVGファイルはモダンWebグラフィックスの基盤です -- スケーラブル、スタイル設定可能、アニメーション対応、そして通常はラスター画像より小さいです。しかし、FigmaやIllustratorからエクスポートされた最適化されていないSVGは、PNGより大きくなり、Core Web Vitalsを悪化させる可能性があります。
私は8年間、本番環境でSVGをデプロイしてきました。これは初日に持っていたかったプレイブックです。
SVG最適化がパフォーマンスバジェットの項目である理由
最適化されていないSVGには、エディタのメタデータ、12桁の小数精度を持つ冗長なパス、繰り返されるインラインスタイル、未使用のグラデーション/フィルター定義、xml:space のようなXMLの不要データが含まれることがあります。実際の監査結果:52KBのヒーローイラストが最適化後7.8KBに -- 85%削減。
Core Web Vitalsへの影響: SVG最適化は、ファーストビューのSVGに対するLCP(Largest Contentful Paint)を直接改善し、DOMノードを削減してTBTを低下させます。GoogleのPage Experience UpdateはLCPを重視しています -- ヒーローSVGから40KB削減することで、3G環境でLCPを200-400ms改善できます。最適化されていないSVGを配信しているなら、ランキングシグナルを逃しています。
SVGO設定ウォークスルー
SVGOは業界標準のオプティマイザーです。デフォルト設定で実行すると、パフォーマンスの余地を残してしまいます。調整された設定が必要です。
CLI vs Node API
# CLI -- 単発ファイルとCIスクリプト
npx svgo input.svg -o output.svg --config svgo.config.js
# ディレクトリを一括最適化
npx svgo -f ./src/icons -o ./dist/icons --config svgo.config.js
// Node API -- ビルドパイプライン統合
import { optimize } from \'svgo\';
import { readFileSync, writeFileSync } from \'fs\';
const result = optimize(readFileSync(\'icon.svg\', \'utf8\'), {
multipass: true,
plugins: [
\'preset-default\',
\'removeDimensions\',
{ name: \'removeAttrs\', params: { attrs: \'(data-.*|class)\' } },
],
});
writeFileSync(\'icon.opt.svg\', result.data);
本番用 svgo.config.js
module.exports = {
multipass: true,
plugins: [
{
name: \'preset-default\',
params: {
overrides: {
removeViewBox: false,
convertPathData: { floatPrecision: 2, transformPrecision: 3 },
mergePaths: { force: true },
},
},
},
\'removeDimensions\',
\'sortAttrs\',
{ name: \'removeAttrs\', params: { attrs: [\'xml:space\', \'data-name\'] } },
],
};
Pro Tip: 本番用svgo.config.jsのベストプラクティス: 常に removeViewBox: false を設定してください -- 削除するとレスポンシブスケーリングが壊れます。アイコンには floatPrecision: 2、詳細なイラストには 3 を使用してください。各パスがさらなる最適化を開放するように multipass: true を有効にしてください。設定をリポジトリにコミットして、すべての開発者とCI実行が同じ設定を使用するようにしてください。
Before/After:メタデータとエディタの肥大化を除去
すべてのデザインツールは独自のフィンガープリントを埋め込みます:
<!-- 最適化前:680バイトの無駄 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" id="Layer_1" x="0px" y="0px" width="200px" height="200px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;"
xml:space="preserve">
<!-- Generator: Adobe Illustrator 28.0 -->
<metadata><rdf:RDF><rdf:Description/></rdf:RDF></metadata>
<defs><linearGradient id="unused_grad">...</linearGradient></defs>
<!-- 最適化後:クリーンで本番対応 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
除去されたもの:version、固定寸法、xml:space、enable-background、ジェネレーターコメント、空のメタデータ、未使用のdefs。小さなアイコンで680バイト節約 -- これを40シンボルのスプライト全体で掛け算してください。
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual Dealパス簡素化:視覚的劣化なしのノード削減
パスはSVGバイトの大部分が存在する場所です。デザイナーは数十で十分なところに数百のノードでパスを作成します。
<!-- 最適化前:12桁の小数精度 -->
<path d="M10.123456789012 20.987654321098 C15.111111111111 25.222222222222
30.333333333333 40.444444444444 45.555555555555 50.666666666666"/>
<!-- 最適化後:2桁の小数精度、視覚的に同一 -->
<path d="M10.12 20.99C15.11 25.22 30.33 40.44 45.56 50.67"/>
画面解像度での視覚的差異?ゼロ。 バイト節約?58%。 ノード削減を視覚的に確認するにはVectoSolveのSVGエディターを使用してください。
最適化テクニック比較
| テクニック | サイズ削減 | リスクレベル | 使用タイミング |
|---|---|---|---|
| メタデータとコメントを削除 | 5-15% | なし | 常に -- 視覚的影響ゼロ |
| 小数精度を削減(2-3) | 15-30% | 低 | アイコン、UI要素、ロゴ |
| パスの統合と簡素化 | 10-25% | 中 | 視覚QAチェック後 |
| 未使用のdefsとシンボルを削除 | 5-20% | 低 | 常に -- デッドコード除去 |
| グループとコンテナの折りたたみ | 3-8% | 低 | CSSがグループを対象にしていない場合 |
| インラインスタイルをattributeに変換 | 2-10% | 低 | HTML内のインラインSVG用 |
| Gzip圧縮(サーバー) | 70-80% | なし | 常に |
| Brotli圧縮(サーバー) | 75-85% | なし | CDNがサポートしている場合 |
SVG内のCSS:インライン vs 外部スタイルシート
<!-- インラインスタイル:肥大化するが自己完結型 -->
<path style="fill:#ff0000;stroke:#000;stroke-width:2" d="..."/>
<path style="fill:#ff0000;stroke:#000;stroke-width:2" d="..."/>
<!-- 統合された<style>:より小さく、自己完結型 -->
<style>.a{fill:#f00;stroke:#000;stroke-width:2}</style>
<path class="a" d="..."/>
<path class="a" d="..."/>
<!-- プレゼンテーションattribute:最小、インラインSVGに最適 -->
<path fill="#f00" stroke="#000" stroke-width="2" d="..."/>
インラインSVGにはプレゼンテーションattributeを使用 -- 外部CSSでオーバーライド可能、スコープの問題なし。スタンドアロンファイルには <style> ブロックで問題ありません。
Warning: 過度な最適化はアニメーションを壊します。 SVGがCSSアニメーション、currentColor、JSリスナー、またはSMILを使用している場合:removeHiddenElems はアニメーションターゲットを削除し、collapseGroups はグループ変換を破壊し、cleanupIds はCSS/JSが参照するIDを名前変更し、removeUselessStrokeAndFill はホバー状態のストロークを削除します。最適化されたSVGは必ずコンテキスト内でテストしてください。
Free SVG Tools for Crafters
Design Checker · Color Separator · Mat Preview · Offset Generator · Text to SVG
Check Your SVG FreeGzipとBrotliの圧縮統計
SVGはXMLです -- 驚異的に圧縮されます:
| アセット | 生 | SVGO | Gzip | Brotli |
|---|---|---|---|---|
| ヒーローイラスト | 52KB | 7.8KB | 2.4KB | 2.1KB |
| アイコンスプライト(40個) | 38KB | 11KB | 3.2KB | 2.8KB |
| アニメーションロゴ | 18KB | 9.2KB | 3.1KB | 2.7KB |
| 複雑なインフォグラフィック | 124KB | 34KB | 9.8KB | 8.6KB |
BrotliはSVGでGzipを5-15%上回ります。Cloudflare、Vercel、Netlifyは標準でサポートしています。
「配信するすべてのキロバイトは、ユーザーのブラウザがダウンロード、解析、レンダリングしなければならないキロバイトです。最適化されたSVGはあれば良いものではありません -- パフォーマンスバジェットの項目です。」 - Addy Osmani
SVG多用ページの遅延読み込み
ページにファーストビュー以下に20以上のSVGがある場合、すべてをペイント時に読み込まないでください:
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, { rootMargin: \'200px\' });
document.querySelectorAll(\'img[data-src$=".svg"]\' ).forEach(img => observer.observe(img));
200pxの rootMargin でブラウザに先読みの余裕を与えます。レイアウトシフトゼロ、帯域幅の無駄ゼロ。
ビルドパイプライン統合:Webpack、Vite、Next.js
手動最適化はスケールしません。SVGOをビルドツールに組み込みましょう。
Vite
import svgLoader from \'vite-svg-loader\';
export default defineConfig({
plugins: [svgLoader({
svgoConfig: { multipass: true, plugins: [\'preset-default\', \'removeDimensions\'] },
})],
});
Webpack
{ test: /\\.svg$/, use: [
{ loader: \'svg-url-loader\', options: { limit: 8192 } },
{ loader: \'svgo-loader\', options: { configFile: \'./svgo.config.js\' } },
]}
Next.js
config.module.rules.push({
test: /\\.svg$/,
use: [\'@svgr/webpack\', {
loader: \'svgo-loader\',
options: { configFile: \'./svgo.config.js\' },
}],
});
パイプライン統合により、最適化はビルド時に実行されます。手動ステップなし、忘れたファイルなし。
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual Deal完全な最適化チェックリスト
- デザインツールからクリーンにエクスポート
- コミットされた設定でSVGOを実行 -- または視覚的ワークフローのためにVectoSolveで最適化
- 視覚的に検証 -- 最適化前後の差分を確認、特にアニメーション
- 圧縮を有効化 -- 最低限Gzip、CDNがサポートしていればBrotli
- ファーストビュー以下のSVGを遅延読み込み -- Intersection Observerを使用
- CIで自動化 -- パイプラインにSVGOを組み込み、最適化されていないものを一切デプロイしない
ラスター画像を最適化されたSVGに変換する必要がありますか?VectoSolveがベクタライズと最適化を一つのステップで処理します。またはパスと出力品質の詳細な制御にはSVGエディターを使用してください。
ご質問や最適化の実体験はありますか?contact@vectosolve.com までお気軽にどうぞ。
| 最適化テクニック | 一般的なサイズ削減 | リスクレベル |
|---|---|---|
| 調整された設定のSVGO | 60–85% | 低(テスト付き) |
| 小数精度削減(8 → 2) | 20–40% | シンプルなグラフィックでは低 |
| エディタメタデータの削除 | 10–30% | なし |
| パス簡素化 | 15–50% | 中(カーブが変わる可能性) |
| Brotli圧縮(サーバー) | 転送サイズ75–90% | なし(ロスレス) |
参考文献・関連資料
- web.dev: Image Optimization — Webパフォーマンスのためのsvg最適化と圧縮に関するGoogleの公式ガイド
- MDN Web Docs: SVG — 最適化対象のSVGパス構文と要素attributeの技術リファレンス
- CSS-Tricks: Optimizing SVG — 実践的なSVGO設定チュートリアルとビフォー・アフターの最適化例
- W3C SVG 2 Specification — どのSVG attributeを安全に削除できるかを理解するための公式仕様