ユーザーに優しい日本語Webフォントとの付き合い方

## はじめに

日本語Webフォントはデータ量が非常に大きいため、何も考えずに使うとユーザー体験を悪化させてしまいます。
この記事では、ユーザーに優しく日本語Webフォントを使うために考えること/できることを紹介します。
主観的な内容を含む(特に前半)ので、あくまで考え方の一つとして参考程度に読んでいただければ幸いです。

(この記事は [DeNA 20 新卒 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/dena-20-shinsostu) の3日目です。)

## (ビジュアルがメインのコンテンツでなければ)日本語Webフォントはできるだけ使わない

最近はスマートフォンでの閲覧が多くなっているので、通信量を消費するコンテンツは今まで以上にそのトレードオフを考慮する必要があります。
サイトに来るユーザーは何を求めているでしょうか？
映画のサイトであれば、フォントが世界観を伝える助けになってくれるかもしれません。
でも、例えばそれがニュースサイトだったら？ユーザーが知りたいのは記事の内容であって、サイトの派手さに興味は無いはずです。

勿論、読みやすさを向上させる効果もあります。
ただ、私の考えとして、影響は比較的限定的だと考えています。
普段サイトを見ていて大きな不便を感じたことはないですし、恐らく多くの人にとってもそうだと思います。
デバイスのフォントだけで十二分に可読性を確保できるはずです。

とはいえ、最終的にはケースバイケースです。
SPAなど、滞在時間が長いページであれば、読み込み時間を割くだけのメリットが得られるかもしれません。
ユースケースに当てはめて検討してみてください。

## ユーザーに優しく日本語Webフォントを使う

使うと決まっても、まだユーザーのためにできることがいくつかあります。
ここでは、ユーザーに優しく日本語Webフォントを使うためにできることを3つ紹介します。

### 読み込み中の表示を考える

CSSのfont-displayプロパティで、読み込みが完了するまで表示しないか、読み込みが完了するまで代替フォントで表示するかを選択できます。
読み込みが完了するまで表示しないようにした場合、読み込み完了時に突然文字がズレる現象を防げますが、読み込みが完了するまで文章が読めないという大きなデメリットを背負うことになります。
個人的には、読み込み中に文章を読むことも多いですし、代替フォントでの表示がオススメです。

memo: 2019年夏頃から、Google Fontsでもfont-displayを指定できるようになっています。
https://twitter.com/googlefonts/status/1130542400131293185

### woff2/woffのような圧縮フォーマットに変換して利用する

woff2/woffはwebフォント向けに最適化されたフォント形式で、ttf/otfに比べてファイルサイズを小さく抑えることができます。
これらの形式に変換することで、転送量を削減できます。
(※クラウドサービスを使う場合は、一般的にwoff2/woffが使われているので気にする必要はありません)

memo: woff2/woff2は `Web Open Font Format` の略で、可逆圧縮(ex. Deflate(zip)など)を活用したWebフォント形式です。また、メタデータを含めることもできます。

### 不必要な文字はできるだけ読み込まない

フォントから不必要な文字を取り除くことをサブセット化と言います。
サブセット化のアプローチにもいくつか種類があるので、ここでは3つの方法を紹介したいと思います。
(※クラウドサービスでは必然的に提供されている実装の中から選ぶことになります)

#### JIS第1水準・第2水準漢字など、普段使う文字だけに絞り込んだフォントを生成する
日本語記事でよく紹介させているものがこれです。
メリット: **使い方がサブセット化前と変わらず、シンプルに扱える,キャッシュを活かしやすい**
デメリット: **これでも1000文字は軽く超えてしまう**

#### unicode-rangeプロパティにより複数のサブセットに分割する

Google FontsやAdobe Fontsで用いられているものがこれです。
ただサブセット化するだけでなく、細かく複数のサブセットに分割し、cssのunicode-rangeプロパティで `U+0000～U+1000の文字はこのサブセット` といった指定を行います。
必要な文字が含まれるサブセットだけを読み込むようになるので、単一のサブセットを生成する場合に比べ、より転送量を減らすことができます。
メリット: **CSSこそ長くなるもののJSに依存せず、読み込む文字数も単純なサブセット化より少なくできる,キャッシュを活かしやすい**
デメリット: **古いブラウザはunicode-rangeプロパティをサポートしていない**

#### 動的に必要な文字だけのサブセットを生成する

FONTPLUSやTypeSquareなどのクラウドWebフォントサービスで用いられているものがこれです。
JavaScriptで使われている文字を調べて、必要な文字だけのサブセットを動的に取得してくれます。
また、textareaなどで文字が変化した時に、足りない文字を動的に取りに行ってくれる機能もあったりします。
メリット: **通信量を最低限に抑えることができる**
デメリット: **JSに依存する,キャッシュを活かしづらい,現状OSSは存在せず、自分でフォントをホストする場合は使えない** (OSSを作ってもいいのよ?)

## クラウドサービスを使う

クラウドサービスには3つのメリットがあります。

- ライセンスを気にする必要がない
- これまでに紹介してきた最適化を(ほとんど)意識することなく、お手軽にユーザーに優しい日本語Webフォントを導入できる
- 動的サブセットでなければ、同じフォントを利用している別サイトのキャッシュが活かせる

有料フォントを使いたい時は、ライセンスの都合で必然的にクラウドサービスを使うことが多いかもしれません。
色々よしなにやってくれて便利ですが、どんな最適化を行っているかはサービスによって様々なので、詳しくドキュメントを確認することをオススメします。

著名なサービス一覧

|  サービス名  | 料金 | 複数サブセット*1 | 動的サブセット*1 |
| ---- | ---- | ---- | ---- |
| Google fonts | 無料 | ○ |  |
| Adobe Fonts | 有料 | ○ | ○ |
| FONTPLUS | 有料 |  | ○ |
| Typesquare | 有料 |  | ○ |

*1 サブセットについては前段落を参照

## まとめ

- まず読み込みコストに見合う価値があるかを検討する
- 使い方の工夫で読み込みコストを軽減する
    - 読み込み中も文字を表示するようfont-displayプロパティを指定する
    - woff/woff2などの圧縮Webフォントフォーマットに変換して利用する
    - サブセット化する
        - 普段使う文字だけにする
        - 複数のサブセットに細かく分割する
        - 動的に必要な文字だけのサブセットを生成する
    - クラウドサービスを使う
        - お手軽に最適化済みのWebフォントを導入できる
        - どんな最適化を行っているかドキュメントを確認しよう

ユーザーに優しく日本語Webフォントを使っていきましょう

## おまけ: Google Fontsはどのような範囲で複数のサブセットに分割しているのか？

試しにNoto sans JPを調べてみました
https://gist.github.com/mochiya98/ca412fca2d93f0ed5b06e89164caab39

…よく分からず。出現頻度順…とかなのかな…？