PenpotのSVGを「兵器」に変える:プロダクション・グレードのクリーンアップ自動化戦略
デザインツールから吐き出されるSVGは、多くの場合「ゴミ」の塊だ。Penpotはオープンソースの旗手として素晴らしいUIを提供しているが、エクスポートされるSVGには、編集履歴やツール固有のDOM構造、メタデータが冗長に含まれる。これらはプロダクション環境において、単なるファイルサイズの増大を招くだけではない。レンダリングエンジンのパース負荷を増大させ、初期描画の遅延(LCP/FCPの悪化)に直結する。
我々エキスパートにとって、デザインデータは「そのまま使うもの」ではなく、「最適化すべきソースコード」である。今回は、Penpotから出力されたSVGを、CI/CDパイプライン上で完全にクレンジングし、超軽量なアセットへと昇華させるためのアーキテクチャを伝授する。
—
1. なぜ「手作業」のクリーンアップは死を招くのか
デザイナーがPenpotで修正を繰り返すたび、SVGには`id=”g1234″`のようなランダムな識別子や、不必要な`defs`、さらには`metadata`タグが蓄積される。これを手動で消すのはエンジニアリングの敗北だ。
我々が目指すべきは「Penpotからのエクスポートをトリガーにした、完全自動のSVG最適化パイプライン」である。
—
2. ツールチェーンの選定:SVGOとNode.jsの融合
最適化の核となるのは、業界標準の`SVGO`だ。しかし、ただ`svgo`を叩くだけでは不十分。Penpot特有の構造を叩き潰すための「カスタム設定」が必要になる。
カスタム設定ファイル:`svgo.config.mjs`
// SVGOの真髄はプラグインの取捨選択にある
export default {
multipass: true, // 複数回パスを通して圧縮効率を極限まで高める
plugins: [
‘preset-default’,
‘removeDimensions’, // width/heightを除去し、viewBoxでスケーラビリティを確保
{
name: ‘cleanupIDs’,
params: {
minify: true, // IDを最短の文字列に変換
remove: true, // 未使用のIDを完全削除
},
},
{
name: ‘removeAttrs’,
params: {
// Penpotが注入する不必要な属性を根こそぎ落とす
attrs: ‘(stroke-opacity|fill-opacity|data-name|id)’,
},
},
‘removeScriptElement’,
‘removeViewBox: false’, // viewBoxは必須
],
};
—
3. パイプラインへの統合:CI/CDの自動化ハック
単にローカルで動かすのではない。Gitの`pre-commit`フック、あるいはCI/CDのビルドパイプラインに組み込むことで、デザインとコードの乖離を物理的に封じる。
自動化スクリプト:`optimize-assets.sh`
!/bin/bash
SVGアセットを監視し、Penpotエクスポート直後に自動でクレンジングを実行する
INPUT_DIR=”./src/assets/raw-svg”
OUTPUT_DIR=”./src/assets/optimized-svg”
SVGOを直接実行。npxを使用することでローカル環境を汚さない
find “$INPUT_DIR” -name “.svg” | xargs -I {} npx svgo {} –config=svgo.config.mjs -o “$OUTPUT_DIR/$(basename {})”
echo “SVG最適化完了: パフォーマンス・バジェットを遵守しました。”
—
4. 上級者向け:内部アーキテクチャへの介入
さらに一歩進んで、SVGの構造そのものを制御したい場合、`svgo`のAPIを直接叩くNode.jsスクリプトを書くべきだ。これにより、例えば「特定の`path`ノードを`symbol`に変換して`defs`に集約する」といった、高度なスプライト化を自動で行うことが可能になる。
import { optimize } from ‘svgo’;
import fs from ‘fs’;
const svgData = fs.readFileSync(‘raw.svg’, ‘utf-8’);
// カスタムの変換ロジックを注入
const result = optimize(svgData, {
path: ‘raw.svg’,
plugins: [
{
name: ‘custom-cleanup’,
fn: (ast) => {
// ASTを直接走査し、特定の条件でDOMを操作する高度なハック
// 例:すべてのパスのfillをcurrentcolorに強制変換
return {
element: {
enter: (node) => {
if (node.name === ‘path’) {
node.attributes.fill = ‘currentColor’;
}
}
}
};
}
}
]
});
fs.writeFileSync(‘optimized.svg’, result.data);
—
5. 結論:デザインシステムとしてのSVG管理
SVGを「画像」として扱うな。「コンポーネントのソース」として扱え。
PenpotからエクスポートされたSVGをこのパイプラインに通すことで、以下が実現する。
1. ファイルサイズ削減: 平均30-60%の軽量化。
2. 保守性の向上: 全SVGが統一された命名規則と属性を持ち、CSSからの制御(`currentColor`等)が容易になる。
3. 人的ミスの排除: デザイナーがいかなる操作をしようとも、ビルドプロセスがそれを「正規の形式」に強制変換する。
これこそが、ツールに振り回されるのではなく、ツールを掌中に収めたエンジニアの仕事だ。Penpotの進化と共に、このパイプラインをより堅牢に、より不可視なものへと洗練させていけ。
君たちのプロダクトの、その最後の一滴のレンダリング負荷まで削ぎ落とせ。それが究極のUI/UXへの敬意である。