Webフォントを分割、というか削りたい

/web/html-css

Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。

@font-face {
    font-family: "FontAwesome";
    src: url('/font/fontawesome-webfont.eot');                                    /* IE9 Compat Modes */
    src: url('/font/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
    url('/font/fontawesome-webfont.woff') format('woff'),                         /* Modern Browsers */
    url('/font/fontawesome-webfont.ttf') format('truetype'),                      /* Safari, Android, iOS */
    url('/font/fontawesome-webfont.svg#FontAwesome') format('svg');               /* Legacy iOS */
    unicode-range: U+f017,U+f02d,U+f040,U+f016,U+f07c,U+f02d,U+f013;
}

HTTPリクエスト削減の一環としてWebフォント・アイコンを導入した。
ただまあ半分も使ってないので、使わない分を削りたい。スマホだし軽くしたいよね ...という案件。使わないWebフォント部分を削ってみるテスト。

ところがまあ、ググってみると「Webフォント 削る」でも「Webフォント 高速化」でも「Webフォント 分割」でも引っ掛からなかった。 「Webフォント サブセット化」なら山ほど引っ掛かる。みんな専門用語を使いすぎでしょうよー。ふぁっくふぁっく。なので記事書いてみた。

ちなみに参考コード中の「?#iefix」の意味はPaul Irishさんが記事書いてくれてます
これによると重要なのは「?」であって後は要らないんだけど、書かないと(うっかり)消されちゃいますよね

さて、フォント分割まわり。使用フォントはFont Awesome。アイコン数が多いので重宝してます。出自の違うアイコンを組み合わせると違和感あったりしますからねー。俺は気になるタイプ。

Webフォントを分割する方法は幾つかある。

unicode-rangeを指定する
@font-face宣言のなかでunicode-rangeプロパティを用いると、使用する文字セットをピンポイントで抜き出すことができる。
ソフトウェアで分割する
サブセットフォントメーカーなど。フォントファイルを読み込んで、必要な部分だけ抜き出したファイルを出力する。
フォント編集ソフトで追加/削除する
OTEdit、WinだとTTEdit、MacだとGlyphsなどがある。「フォントを作るためのソフトウェア」で必要な文字セットだけのファイルを作る。
オンラインの変換サービスを用いる
@FONT-FACE GENERATORなど。この場合、オプションにunicode-rangeを記入する項目があるので、そこで使用文字を入力するとサブセット化できる

memo: 基本的に「改変・再配布」に当たるので、ライセンスに気をつけてくださいね−。アイコンフォントに限れば、元がWebフォント前提に作られているので大抵は緩いですが。

memo: Vimだと、ノーマルモードで「ga」とするとカーソル位置の文字コードを表示してくれるので便利(unicode-range的に)。

Try & Error

結論を先に言うと、@FONT_FACE GENERATOR を利用しました。

unicode-range
ダウンロードサイズは変化しない。「日本語フォントはunicode-rangeを使うと軽い」的な文脈でどっか見た気がするんだけども使われないフォントファイルをダウンロードしないだけ混植には有用。
サブセットフォントメーカー
サブセット化する文字をテキストで入力する。今回、Font Awesome ではUnicodeの私用領域にアイコンを設置していて、コピペできなかった。
OTEdit
課金しないと1文字しか保存できない。CSVで文字範囲をしていする「一括コピー」では、サイズが肥大化し、私用領域が空に。つまりアイコンが消えた。
Glyphs
Mac用の売れ筋ソフトだけあって、とても使いやすい。インターフェイスも洗練されています。サブセット化も問題なくできたのですが、実際にWebフォントとして使うと何故かゲタに...
@FONT-FACE GENERATOR
特に問題なし

まあ今回の場合は、肝心のアイコンがUnicodeの私用領域に割り当ててあった(つまりaとかbとかいう通常の文字じゃない)ので面倒な部分もアリ。今回ボツだったものも日本語フォントでは有用であったりと、場合によりけりです。

効果

結果的にはフォントの未使用領域を削ることによって、フォントファイルのダウンロードサイズは40kbから7kbまで削減されました。幅300px前後のバナー広告が3kbくらいだとして、だいたい10枚分くらいでしょうか。こう考えるとけっこう大きいですね。

分割前の画像。40.7kb
↓↓↓
分割後の画像。6.9KB

宿題

この辺、後で見直す

The user agent again first checks the unicode-range of the font containing Latin characters. Since U+2000-2300 includes the arrow code point (U+21E8), the user agent downloads the font. For this character however the Latin font does not have a matching glyph, so the effective unicode-range used for font matching excludes this code point. Next, the user agent evaluates the Japanese font. The unicode-range for the Japanese font, U+3000-9FFF and U+ff??, does not include U+21E8, so the user agent does not download the Japanese font. Next the fallback font is considered. The @font-face rule for the fallback font does not define unicode-range so its value defaults to the range of all Unicode code points. The fallback font is downloaded and used to render the arrow character.

4.5. Character range: the unicode-range descriptor

「該当する文字が指定したunicode-range内だったらフォントをダウンロードするけど、違ったらダウンロードしないでfallback fontを使うよ」と読み取れる。つまり部分ダウンロードするって話じゃなくて、単に使わないよと。まあ部分ダウンロードって、技術的にできるか怪しいよね。

Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。