和文フォントを軽くする
和文フォントは収録字数が数千から数万あり、そのままでは数MBの転送になります。削り方は2つです。使う文字だけを抜くか、範囲で分けて必要な分だけ届けるかです。
Webフォントの実装 で「和文はサブセット化が必須」と決めたあとの、実際の手順です。着手する前に、ライセンスを確かめます。
先にライセンスを確かめる#
サブセット化はフォントファイルの改変にあたります。配って良いか、変えて良いかは、フォントごとに条件が違います。
| ライセンス | できること |
|---|---|
| SIL Open Font License(Noto・Zen 系など) | Web 埋め込みもサブセット化も可。予約フォント名の条件だけ確認する |
| 商用フォントの多く | Web 埋め込みやサブセット化が別契約のことがある。規約を読む |
| Google Fonts をそのまま使う | サブセット済みの配信をリンクするだけ。自分で加工しない |
方法1 使う文字だけ抜く(文字が固定のサイト向け)#
LPや会社案内のように文章が決まっているサイトなら、実際に使う文字だけを抜き出せます。fonttools の pyftsubset を使います。
pip install fonttools brotli
# text.txt にはサイトで使う全文を貼っておく
pyftsubset ZenOldMincho-Regular.ttf --text-file=text.txt --flavor=woff2 --layout-features+=palt --output-file=zen-old-mincho-400.woff2
--flavor=woff2の圧縮に brotli が要る。ウェイトごとに1回ずつ実行する--layout-features+=paltを付けないと、詰め情報が削られて"palt"が効かなくなる- 落とし穴は更新です。あとから文章に無い文字が増えると、その文字だけ代替書体で出ます。フォールバックのスタックを必ず書き、更新のたびに text.txt を作り直します
方法2 範囲で分けて配信(文字が増え続けるサイト向け)#
お知らせやブログのように文章が増えるサイトでは、文字を固定できません。かなと漢字をファイルに分け、@font-face の unicode-range で宣言します。ブラウザは、ページに実際に現れた文字を含むファイルだけを取りに行きます。
このコードで動いている見本です
分割そのものは方法1と同じ pyftsubset で、--unicodes=U+3040-30FF のように範囲を指定して作ります。Google Fonts の和文はこの方式を細かくしたもので、1書体を多数の小さなファイルに割って配信しています。自前なら2〜3分割でも効きます。
最初の画面で使うぶんだけ先読みする#
見出し用のかなファイルのように、確実に使うものだけ preload します。全ファイルを preload すると、分割した意味がなくなります。
このコードで動いている見本です
crossorigin は同一オリジンから配信する場合にも必要です。付けないと同じファイルが2回取得されます。
確認する#
- DevTools のネットワークで、転送された woff2 の本数と合計サイズを見る(絞った結果が数字で出る)
- 原稿に新しい文字を足したページで、その文字が豆腐や代替書体になっていないか
"palt"を使うサイトでは、サブセット後も詰めが効いているか