svgo を使って SVG フォントを最適化する、その際の注意点は?
「アイコンの為に Web フォント、合字を深堀してフォールバックを検討する」での調査を元に「<font>
タグの id 属性は残す」の id が必要なブラウザに iOS Safari 3~4 を追記。(2024/01/26)
「エンティティ」表記を「数値文字参照」に修正しました。追記と修正をしています。(2023/08/16)
icomoon で作成した SVG フォントを svgo 3.0.2 で最適化したところファイルサイズは、53KB から 23KB へ43%になりました。 その注意点と svgo の設定をご紹介します。
因みに、svgo は SVG フォントを最適化することにも使われていますが(issue 140:Hex Entities Incorrectly Converted to Unicode)、公式にサポートされてはいません。自分でトライエラーを繰り返して設定を特定しました。
unicode 属性を数値文字参照へ
icomoon が出力する SVG フォントを参考に unicode 属性を数値文字参照にしていますが、この処理は不要かもしれません。いずれ各ブラウザでチェックして追記します。(2023/08/16 追記)
<glyph unicode="🏠" d="..." />
↓
<glyph unicode="🏠" d="..."/>
先の issue 140にある通り、svgo が利用している XML パーサーの sax は unicode 属性の数値文字参照を解除してします。これを再び数値文字参照にします。
svgo のコードを見ていくと、XML DOM をテキスト化する工程をカスタマイズする手段が無いようなので、文字列操作で数値文字参照にしました。詳しくは web-doc-base / js-buildtools / web-font.js 127行を確認ください。
<font>
タグの id 属性は残す
id 属性は削除しません。そして一部のブラウザは CSS 側でフォントの URL のハッシュフラグメントに id を指定しないとフォントが適用されません。id が必要なブラウザは、Chrome 1~5, Safari 3.1~3.2, iOS Safari 3~4, Presto Opera でした。
<font id="web-doc-base" horiz-adv-x="1024">
@font-face {
font-family: myIconFont;
font-weight: 400;
font-style: normal;
src: url(icon.eot?rw1juc);
src: …, url(icon.svg?rw1juc#web-doc-base) format("svg")
}
SVG フォントの制限
余談になりますが、つまりこれらのブラウザでは Data URI 化して CSS に埋めることができません。Data URI ではハッシュフラグメントを表現できないためです。そもそも CSS 化したフォントは、ネットワークの最適化ツールのブロックのすり抜けを狙っています。しかし、他のフォント形式と異なり、画像形式である SVG はネットワークの最適化ツールのブロック対象からはお目こぼししてもらえそうですので、問題にならないようにも思います。
最適化
この為のオプションは web-doc-base / js-buildtools / web-font.js 55行にあります。
最適化しない属性
半角スペースのグリフを最適化から保護します。この為の指定が cleanupAttrs:false
, removeEmptyAttrs:false
です。
<glyph />
↓
<glyph unicode=" " d="" />
パスデータを整数に丸めて glyph-name 属性を削除
整数に丸める事で SVG フォントのファイルサイズを大きく削減出来ます。例えば icomoon の出力する SVG フォントの論理空間は 1024x1024 と巨大ですので、アイコンや通常のテキストとして使う分には目視できる副作用はありません。(2023/08/16 修正)
glyph-name 属性は、先の unicode 属性と同様に文字列操作で削除しました。
<glyph unicode="Windows" glyph-name="Windows" d="M0.35 384l-0.35 312.074 384 52.144v-364.218zM448 757.518l511.872 74.482v-448h-511.872zM959.998 320l-0.126-448-511.872 72.016v375.984zM384-47.836l-383.688 52.594-0.020 315.242h383.708z" />
↓
<glyph unicode="Windows" d="M0 384v312l384 52V384zm448 374 512 74V384H448zm512-438v-448L448-56v376zM384-48 0 5v315h384z"/>