この記事の要点(TL;DR)
- 個人開発のサイトに好きな日本語フォント(丸ゴシック)を使ったら、文字の表示が遅くなる問題に当たりました。
- 原因は、日本語フォントのファイルがとても大きいこと。日本語は文字数が数千〜1万以上あるので、フォント1個で数MBにもなります。
- 直し方は「フォントを小さく分割して、必要な分だけ読み込ませる」+「自分のサーバーに置く(自前ホスト)」でした。
「Webフォントってなんか重いよね」でモヤっとしている初心者向けに、仕組みから書きます。
そもそもWebフォントって?
パソコンやスマホには最初から入っているフォント(游ゴシックなど)があります。でも「このかわいい丸ゴシックを使いたい」と思うと、その字体は端末に入っていないので、フォントのファイルを配信して読み込ませる必要があります。これがWebフォントです。
ここで問題になるのがファイルサイズです。アルファベットだけの英語フォントは文字数が少ないので軽いのですが、日本語は漢字・ひらがな・カタカナで数千〜1万文字以上あります。全部入りのフォントは平気で数MBになり、これをまるごとダウンロードさせると、文字が出るまで真っ白 or もたつくという体験になります。
何が起きたか
サイトの「見た目の第一印象」を測る指標に LCP(Largest Contentful Paint=ページの一番大きな文字や画像が表示されるまでの時間) というものがあります。これが遅いと「表示が遅いサイト」と判定されます。
好きな日本語フォントを入れたら、このLCPが目に見えて悪化しました。原因を追うと、重い日本語フォントの読み込みがページ表示の足を引っ張っていたのです。
直し方1:フォントを「使う文字のかたまり」ごとに分割する
ポイントは、**「1ページに実際に出てくる文字は、フォント全体のごく一部」**ということです。であれば、フォントを小さなかたまり(サブセット)に分けて、そのページで必要なかたまりだけダウンロードさせればいいわけです。
CSSには、そのための unicode-range という仕組みがあります。これは「このフォントファイルは、この範囲の文字を担当します」と宣言するもので、ブラウザはページに出てくる文字が含まれるファイルだけを賢く取りに行ってくれます。
@font-face {
font-family: 'マイフォント';
src: url('/fonts/myfont-0.woff2') format('woff2');
/* このファイルは、この文字コード範囲の文字だけ担当 */
unicode-range: U+3042, U+3044, U+3046 /* ...あ、い、う... */;
}
@font-face {
font-family: 'マイフォント';
src: url('/fonts/myfont-1.woff2') format('woff2');
unicode-range: U+4e00, U+4e8c /* ...一、二... */;
}
こうしておくと、たとえば「一」を含むページを開いたときだけ myfont-1.woff2 が読み込まれ、使わないかたまりはダウンロードすらされません。実際のサイトでは、日本語フォントを太さ2種類 × 4つのかたまり=合計8ファイルに分割しました。
フォントを実際に小さく切り出す(サブセット化する)ツールとしては、
fonttools(Python)やsubset-fontなどがあります。Google Fontsが配信しているCSSも、実はこのunicode-rangeで細かく分割された作りになっているので、参考になります。
直し方2:フォントを「自前ホスト」する
もう一つやったのが、フォントファイルを自分のサイト(public/fonts/ など)に置いて配信することです。これを「自前ホスト(セルフホスト)」と呼びます。
外部のフォント配信サービスから読み込む方法もありますが、
- 別のドメインに毎回つなぎに行くぶん、最初の接続に時間がかかることがある
- 自分でファイルを持っていれば、上のサブセット分割も自由にできる
という理由で、自前ホストにしました。woff2 という圧縮の効くフォント形式で置くと、さらに軽くなります。
さらに「最初の表示で確実に使うフォントファイル」だけは、preload(先読み)で早めに取りに行かせると効果的です。ただしpreloadは本当に必要な1〜2ファイルだけにするのが鉄則で、なんでもかんでもpreloadすると逆に表示が遅くなります(これで一度失敗した話は別記事に書いています)。
やってみた結果
- 全部入りの重いフォントを一度に読ませていた状態から、実際に使う文字のかたまりだけを読む状態になり、フォント関連のダウンロード量が大きく減りました。
- LCP(表示の速さの指標)も改善しました。
まとめ
- 日本語Webフォントが重いのは、文字数が多くファイルが大きいから。
-
unicode-rangeでかたまりに分割すると、ページで使う分だけ読み込まれて軽くなる。 - 自前ホスト+woff2形式にすると管理も速度も扱いやすい。
-
preload(先読み)は効くけど、本当に必要なファイルだけに絞ること。
「好きなフォントを使いたいけど重くなるのがこわい」という人は、まず分割と自前ホストから試すのがおすすめです。