Featured image of post Webフォントのロード最適化:FOUTを防ぎレイアウトずれを解消する Featured image of post Webフォントのロード最適化:FOUTを防ぎレイアウトずれを解消する

Webフォントのロード最適化:FOUTを防ぎレイアウトずれを解消する

Webフォントのロード最適化によるFOUT/FOIT防止とCLS解消方法を徹底解説。font-display: swapの適切な設定、フォント表示領域の事前確保、サブセットフォントの活用など、レイアウトシフトを最小限に抑える実践テクニックを網羅します。

はじめに

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"

セルフホスティングの場合は、言語ごとにサブセットを生成しましょう。glyphhangerfonttools を使えばファイルサイズを 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を最小化しましょう。これらのテクニックを組み合わせることで、速くて安定した美しいタイポグラフィを実現できます。