SVG入力と再実行
本章では,ツールのデータ読み込み手順と変換の実行方法について詳細に解説します.本ツールは,1回につき1つのSVGファイルまたは1件のテキストコードを入力として受け付けます.「元データ入力」エリアにある破線で囲まれた領域に対して,ファイルをドラッグ&ドロップするかクリックしてダイアログから選択すると,内部のFileReader APIがテキストとしてデータを読み込み,直下のテキストエリアに反映させます.
手動でクリップボードからコードを直接貼り付けることも可能です.データの読み込みとそれに伴う変換処理は,利用中のブラウザ内でDOMParserを用いて実行されます.
ファイル読み込み直後は自動的に一回目のパースが行われて結果が表示されますが,左側のパネルで削除設定のスイッチを切り替えた場合や,テキストエリア内のコードを手動で書き換えた場合は注意が必要です.新しい設定や変更を反映させるためには,パネル下部の「最適化を実行」ボタンを再度クリックしなければなりません.
ボタンを押さずにスイッチを変更しただけでは,出力側のコードやプレビューは一切更新されません.万が一構文エラーのあるXMLコードが入力された場合,「無効なSVG形式です」とエラー表示が出て,前回の成功出力結果はクリアされます.
五つの削除規則
ツールが提供する削除処理は,パースされたDOMツリーを探索しながら特定の要素や属性を取り除く5つの独立した規則から成り立っており,UI上のスイッチによって個別に有効化・無効化が可能です.
1つ目は「エディタメタデータの削除」で,metadataタグ,sodipodi:namedview,inkscape:gridなど,実際の描画には関与しない設定情報のノードを取り除きます.
2つ目は「名前空間/属性の削除」で,各ノードの属性を走査し,inkscape:やsodipodi:で始まるカスタム属性や,専用の名前空間宣言を検知して消去します.
3つ目は「空のグループ要素を削除」で,子ノードを一つも持たない,あるいは中身が空白のテキストノードのみで構成される<g>タグを再帰的に見つけ出し,削除します.
4つ目は「XMLコメントの削除」で,DOMツリーから文字列へとシリアライズした直後のフェーズにおいて,正規表現を用いて<!--から-->までのコメントブロックを除去します.
5つ目は「スクリプト要素/イベントの削除」で,scriptタグ自体をDOMから完全に取り除く処理と,onから始まる属性(onloadやonclickなど)を削除する処理を行います.
整形とテキスト空白
不要なタグや属性を削ぎ落とした後のSVG文字列は,出力パネル上で「整形(Beautify)」と「圧縮(Minify)」の2つのモードからコード形式を選べます.「圧縮」モードを選択した場合,ツールは正規表現を用い,タグの開始・終了間に存在する空白文字(>\s+<)を検索してスペースを含まない><へと置換処理を行います.
これにより改行やインデントを持たない形へと切り詰められ,出力文字列が詰められますが,実通信の圧縮量や表示速度を測定するものではありません.
一方,「整形」モードでは,要素の階層レベルをカウントしながら,1階層深くなるごとに2つの半角スペースを用いたインデントと改行を挿入して文字列全体を再構築し,コードの構造を人間が確認しやすくします.
ただしSVGの仕様上には,テキスト要素内の空白文字が実際のレイアウト間隔に直接影響を与えるという重要な規則が存在します.本ツールでは,処理の直前に文字列全体を走査し,<text>,<tspan>,<textPath>要素,またはxml:space=属性が一つでも検出された場合は,レイアウト破壊を未然に防ぐために後続の整形処理(改行やインデントの追加)を完全に抑止します.
この条件を満たす場合,整形・圧縮の両方で空白の再配置をスキップします.
サイズ増減の読み方
変換が完了すると,画面の出力パネルに「元サイズ」と「最適化後」のファイル容量,およびその「削減率」が計算されて表示されます.この数値は,入力元の文字列と再構築された出力文字列をそれぞれUTF-8エンコーディングのBlobオブジェクトに割り当て,そのsizeプロパティが持つ実際のバイト数を比較した実測値として算出されます.
削減率は「(元サイズ - 変更後サイズ) / 元サイズ * 100」の数式で計算され,小数点以下1桁としてUI上に描画されます.エディタが自動付与したメタデータなどの削除量が多いほど,削減率は大きくなります.
ただし,本ツールは指定されたタグや属性の構造的な削除のみを実行する仕組みをとっており,SVGOなどの外部ライブラリを用いた高度なパスデータの最適化アルゴリズムは搭載していません.ベジェ曲線のアンカーポイントを間引く,座標の小数の有効桁数を丸める,絶対座標と相対座標を変換して文字数を削るといった,描画データ自体を数学的に改変する処理は行われません.
そのため,既にクリーンな状態のコードや,パスデータが容量の大半を占めるファイルにおいては,処理を実行してもサイズがほとんど減少しない場合や,整形・シリアライズによって増える場合もあります.
プレビューと保存の差
右側の出力パネルには,「プレビュー」と「コード」の2つのタブが実装されています.「プレビュー」タブでは,クリーンアップされた後のSVGがブラウザ上でどのように描画されるかを視覚的に確認できます.この表示領域にはSafeHtmlPreviewというモジュールが使われており,描画用のiframeに対してsandbox属性や,インラインスクリプト実行および外部リソースへの接続を制限するContent-Security-Policy(CSP)が注入された状態で制限付きでレンダリングされます.
しかし,この厳しい制限はあくまで画面上に制限付きで表示させるための,ツール側の一時的な措置に過ぎません.「コードをコピー」ボタンをクリックしてクリップボードに取得する文字列や,「ファイルを保存」ボタンを介してcleaned_vector.svgとして手元にダウンロードされる実データには,プレビュー時のようなCSPヘッダーや追加の表示制限は引き継がれません.
手元に保存される文字列は,第2章で解説した5つの削除規則と選択した出力形式が適用されたコードです.出力データとプレビュー上の制限事項は連動していないことを理解して利用する必要があります.
安全化ではない限界
本ツールの「スクリプト要素/イベントの削除」オプションは,不要なコードを削除してSVGファイルを整理する機能の一つとして提供されており,セキュリティに特化した完全なサニタイザー(無害化ツール)としての要件を満たすことを意図したものではありません.スイッチを有効にした場合,scriptタグの除去やonで始まる属性(onclickなど)の削除処理は実行されますが,これは入力コードをグラフィック表現に近づけるための整理です.
例えば,href属性の中に仕込まれたjavascript:疑似プロトコルを用いた記述や,悪意のある細工が施された不正なベクターデータなど,巧妙なコードをすべて検知してブロックする保証はありません.外部リソースへの参照がそのまま維持される可能性もあります.
本ツールの変換処理は,利用中のブラウザ内で提供された文字列をDOMにパースし,指定のノードを削除した後に再度シリアライズするだけの簡素なロジックです.出力されたSVGファイルがWebサイトのインライン要素として完全に安全に埋め込める状態になるわけではないため,公開環境で利用する場合はシステム側の要件に基づいた専用のXSS対策ライブラリを併用する必要があります.