はじめに
Webフォントはデザインを向上させますが、読み込み中にFOIT(Flash of Invisible Text) やFOUT(Flash of Unstyled Text) といった問題を引き起こします。またフォントの入れ替わりによる**CLS(Cumulative Layout Shift)**も大きな課題です。本記事では、レイアウトシフトを最小限に抑えながらフォントを最適に読み込む方法を解説します。
font-display プロパティ
@font-face ルールの font-display は、フォント読み込み中の表示動作を制御します:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2');
font-display: swap;
}
| 値 | 動作 | 用途 |
|---|---|---|
auto | ブラウザ既定(通常はFOIT) | デフォルト |
block | 約3秒間非表示、その後スワップ | 短いブロック期間 |
swap | 即座に代替フォント表示、読込後にスワップ | 最大の可読性 |
fallback | 約100ms非表示→約3秒間代替、その後スワップ | バランス |
optional | 短いブロック、任意ダウンロード | 低速接続向け |
swap が最も一般的です。代替フォントを即座に表示するため、FOITを完全に排除できます。
クリティカルフォントのプリロード
<link rel="preload"> でフォントのダウンロードを早期に開始します:
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin>
crossorigin属性は必須です。同一オリジンでもCDN経由の場合は必ず付与してください。これがないとプリロードが無視されます。
セルフホスティング vs CDN
| 方式 | メリット | デメリット |
|---|---|---|
| セルフホスティング | 完全制御、DNSルックアップ不要、キャッシュ制御 | 帯域消費 |
| Google Fonts / CDN | 高速エッジ配信、自動サブセット化 | 余分なDNS+TLSハンドシェイク |
クリティカルなフォントはセルフホスティングが有利です。どうしてもCDNを使う場合は preconnect を併用しましょう:
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
フォントサブセッティング
すべてのグリフを含むフォントファイルは帯域を無駄にします。サブセッティングで不要な文字を削除します:
# pyftsubset を使用
pyftsubset NotoSansJP-Regular.otf --unicodes="U+4E00-9FFF,U+3040-309F"
セルフホスティングの場合は、言語ごとにサブセットを生成しましょう。glyphhanger や fonttools を使えばファイルサイズを 100KBから10~20KB に削減できます。
WOFF2の採用
WOFF2 はWOFF比で30~50%高い圧縮率を誇ります:
@font-face {
font-family: 'MyFont';
src: url('/fonts/myfont.woff2') format('woff2'),
url('/fonts/myfont.woff') format('woff');
}
主要ブラウザはすべてWOFF2をサポートしています。第一候補としてWOFF2を指定し、フォールバックにWOFFを置きましょう。
size-adjustによるレイアウトシフト対策
size-adjust デスクリプタを使うと、代替フォントとカスタムフォントの表示サイズを揃えられます:
@font-face {
font-family: 'Fallback';
src: local('Arial');
size-adjust: 95%;
ascent-override: 85%;
descent-override: 20%;
}
Chrome DevToolsの「Rendering > Font Size Adjust」で適切な値を計算できます。これによりフォントスワップ時のCLSを劇的に削減できます。
最適化レシピまとめ
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
@font-face {
font-family: 'Main';
src: url('/fonts/main.woff2') format('woff2');
font-display: swap;
}
body {
font-family: 'Main', 'Fallback', sans-serif;
}
まとめ
Webフォントの最適化には多層的なアプローチが必要です:font-display: swap でFOITを防止し、プリロードで早期ダウンロード、サブセット化でファイル削減、WOFF2で圧縮、size-adjust でCLSを最小化しましょう。これらのテクニックを組み合わせることで、速くて安定した美しいタイポグラフィを実現できます。
