こんにちは。フロントエンドの現場で日々、パフォーマンスチューニングやレンダリングの最適化と格闘している君なら、「Webフォントを読み込んだ瞬間に画面のテキストがガタッとズレる(レイアウトシフト)」あの不気味な現象に一度は頭を抱えたことがあるはずだ。
「よし、おしゃれなカスタムフォントを導入したぞ!」と意気込んでページを開いたら、最初はシステムフォントで表示され、ネットワーク経由でフォントファイル(WOFF2など)がダウンロードされた瞬間に、テキストがバシッと切り替わる。あれ、ユーザー体験として最悪なのはもちろん、Core Web Vitalsの指標の一つであるCLS(Cumulative Layout Shift)のスコアをも容赦なく殴りつけてくる。
今回は、Webブラウザのレンダリングエンジンの裏側でフォントの読み込みとテキスト描画がどう処理されているのか、そして僕たちフロントエンドエンジニアがこの問題にどう立ち向かうべきか、その極意を徹底的に解説しよう。
—
ブラウザの裏側で何が起きているのか? DOM、CSSOM、そしてフォントの運命
まずは、ブラウザがHTMLを受け取ってから画面にピクセルを描画するまでの「闇」を少しだけ覗いてみよう。
ブラウザのパーサーは、HTMLを上から順に読み込みながらDOMツリーを構築し、同時にCSSを見つけてCSSOMツリーを組み立てる。ここで重要なのは、「ブラウザはCSSOMが完成するまで、あるいはレンダリングブロックを引き起こすリソースが解決されるまで、画面を描画したくない(無駄な再描画を避けたい)」という強い意志を持っていることだ。
しかし、テキストのレンダリングにおいて「フォントファイル」の扱いは少し厄介だ。
CSSの `font-family` で指定されたWebフォント(例: `font-family: ‘Inter’, sans-serif;`)に遭遇したとき、ブラウザは次のようなジレンマに直面する。
1. フォントファイルがまだ手元にない。
2. ネットワーク経由でダウンロードするしかないが、これには数10ミリ秒から、モバイル回線なら数秒かかる。
3. 「じゃあ、ダウンロードが終わるまでテキストの描画を完全に待つべきか?」それとも「とりあえず手元にあるフォント(フォールバック)で表示しとくか?」
この挙動の違いが、有名な FOIT と FOUT という悪名高い現象を生み出す。
FOIT (Flash of Invisible Text)
フォントの読み込みが完了するまで、テキストを完全に透明(不可視)にしておくアプローチ。Safariや古いChromeなどが好んで使っていた手法だ。
ユーザーからすると、「あれ、ボタンや見出しの文字が消えてるぞ? バグか?」と思わせてしまい、最悪の場合はタイムアウト(大体3秒程度)するまでテキストが永遠に現れない。
FOUT (Flash of Unstyled Text)
手元にあるフォールバックフォント(メイリオやRobotoなど)で即座にテキストを描画し、Webフォントのダウンロードが完了した瞬間に、ゴソッとフォントを差し替えるアプローチ。
テキストが消えるストレスはないが、文字の幅(メトリクス)が異なるフォント同士で置き換わると、周囲のレイアウトがガタガタと大きくズレる。これがレイアウトシフトだ。
—
救世主 `font-display` プロパティの仕組み
このブラウザの気まぐれな描画挙動を、僕たちのコントロール下に置くために用意されたのが `@font-face` の `font-display` プロパティだ。
現代のフロントエンド開発において、これを理解せずにWebフォントを語ることはできない。
`font-display` には主に以下の4つの値が存在する。実務でよく使う3つに絞って解説しよう。
1. `swap`(実務の第一選択)
- 挙動: FOUTを採用する。最初はフォールバックフォントで即座に描き、フォントのロードが終わったら一瞬でWebフォントに切り替える。
- メリット: ユーザーを「文字が消えて待たされる地獄」から救い出せる。LCP(Largest Contentful Paint)の観点からもテキストを早く表示できるため非常に有利。
2. `block`
- 挙動: FOITを採用する。最大3秒間はテキストを不可視にし、フォントのロードを待ち構える。ロードできなければフォールバックにフォールバックする。
- メリット・デメリット: ブランディングの観点で「どうしてもブランドフォント以外の文字を見せたくない」という特殊な要件以外、現代のWeb開発ではほぼ使わない(パフォーマンスの敵)。
3. `optional`(究極のパフォーマンス追求)
- 挙動: ブラウザに「フォントの読み込みを頑張るかどうかはお任せするよ」と伝えるもの。ネットワーク状況が良ければ読み込んで次回以降に備え、遅ければ諦めてずっとフォールバックフォントを使い続ける。
- メリット: ネットワークが貧弱な環境でのレイアウトシフトを完全にゼロにできる。次世代のパフォーマンスチューニングの切り札。
—
現場で使える!実践的コードとベストプラクティス
理屈はこれくらいにして、明日からそのままプロジェクトにブチ込める実用的なコードを見ていこう。
ここでは、Google Fontsや自社サーバーからホスティングするWoff2フォントを、パフォーマンスと美しさを両立させながら読み込む設定を解説する。
1. `@font-face` の黄金パターン
/
Webフォントの定義
font-display: swap を指定してFOIT(文字が消える現象)を防ぐのが鉄則
/
@font-face {
font-family: ‘MyCustomFont’;
src: url(‘/assets/fonts/MyCustomFont-Regular.woff2’) format(‘woff2’),
url(‘/assets/fonts/MyCustomFont-Regular.woff’) format(‘woff’);
font-weight: 400;
font-style: normal;
font-display: swap; / ← ここが命綱 /
}
/
フォールバックフォントの設定における極意
フォントの「サイズ(メトリクス)」が近いフォールバックを同時に指定し、
FOUT時のレイアウトシフト(ガタつき)を最小限に抑える
/
body {
font-family: ‘MyCustomFont’, -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, “Helvetica Neue”, Arial, sans-serif;
}
2. `` タグによるプリロード(Preload)の活用
重たいフォントファイルをいつまでもネットワークの待ち行列の奥底に眠らせておくのは、パフォーマンスチューニングの観点から大罪だ。
HTMLの `
—
シニアからの現場アドバイス:フォントとレイアウトシフトの戦い方
最後に、現場で後輩によく言うアドバイスをいくつか授けておこう。
1. WOFF2一択でいけ
古いIEのサポートを切った現代のプロジェクトにおいて、`.eot` や `.ttf` を律儀に並べる必要はほぼない。圧縮効率が最強の `.woff2` のみをターゲットにすることで、ファイルサイズを極限まで削り、ダウンロード時間を短縮せよ。
2. アイコンフォントはもう古い、SVGを使え
昔はよく使われた「FontAwesomeなどのアイコンフォント」は、フォントが読み込まれるまで四角い豆腐が表示されたり、読み込み遅延の原因になったりしていた。今どきはCSSのアイコンやSVGスプライト、あるいは `` でインラインSVGを埋め込むべきだ。フォントの役割は「テキストを描画すること」だけに絞ろう。
3. フォールバックのメトリクス(大きさ)を意識しろ
`font-display: swap` を使っても、カスタムフォントとシステムフォントの文字幅が大きく異なると、どうしてもテキストが切り替わった瞬間に周りの要素が押し出される。完全になくすことは難しいが、`font-size` や `line-height` を綿密に調整し、ユーザーが違和感を覚えないレベルに落とし込むのがプロの仕事だ。
Webブラウザが裏側でどうテキストを描画しているか、そのメカニズムを解像度高く理解していれば、単なる「おまじない」ではなく、根拠を持ってコードを書くことができるはずだ。
さあ、君のプロジェクトのフォント読み込み周りも、今すぐ見直してみようじゃないか。

コメント