Webブラウザの「フォント」という名の地雷:FOIT/FOUTを制し、レンダリングを最適化する
やあ。フロントエンドの現場で、「フォントの読み込み待ち」に泣かされた経験はないかな?
「ページが開いた瞬間、文字が消える」「レイアウトがガタガタと崩れる」……これらは単なるデザインの不手際ではなく、ブラウザのレンダリングパイプラインの裏側を知らないと解決できない、かなり根深い問題なんだ。
今日は、ブラウザが裏側でどうやって「フォント」と格闘し、僕たちがそれをどう制御すべきか、プロの視点で解き明かしていくよ。
—
ブラウザは「フォントがない」とき、どう振る舞うのか?
ブラウザのレンダリングエンジン(BlinkやWebKitなど)は、HTMLをパースしてDOMを構築し、CSSを解析してCSSOMを構築する。この二つを合体させて「レンダーツリー」を作るわけだけど、そこで文字を描画しようとしたとき、Webフォントがまだ届いていなかったらどうなると思う?
ここで発生するのが、おなじみのFOIT (Flash of Invisible Text) と FOUT (Flash of Unstyled Text) だ。
1. FOIT: ブラウザが「フォントが来るまで文字を表示させない」という選択をした状態。真っ白なページや、文字が消えたようなUIになる。ユーザー体験としては最悪だ。
2. FOUT: ブラウザが「まずはシステムフォントで表示し、フォントが届いたら差し替える」という選択をした状態。文字は見えるけど、フォントの横幅や行間が変わって、コンテンツが「ガタッ」とずれる現象だ。
ブラウザのデフォルト挙動は、実はブラウザごとに微妙に違う。だからこそ、僕たちが `font-display` プロパティを使って、「どう振る舞うべきか」を明示的に命令してやる必要があるんだ。
—
`font-display` という名の「制御スイッチ」
`@font-face` でWebフォントを読み込む際、`font-display` プロパティを指定しないのは、「ブラウザの気まぐれに任せる」と言っているのと同じだ。実務では、以下の戦略からプロジェクトに合わせて選ぶのが定石だ。
- `block`: FOITを許容する。フォントが来るまで文字を隠す。ブランドロゴなど、フォントが変わると致命的な場合以外は推奨しない。
- `swap`: 一番のオススメ。 FOUTを許容する。即座に代替フォントを表示し、Webフォントが届いたら差し替える。パフォーマンス重視のサイトならまずはこれだ。
- `fallback`: 短いFOITのあと、フォントが遅ければそのまま代替フォントでいく。レイアウトシフトを抑えたい場合に有効。
- `optional`: ネットワークが遅ければWebフォントを諦める。次のページ読み込みまで待つ、という極めて慎重なアプローチ。
—
実践:ベストプラクティスなフォント読み込みコード
現場でそのまま使える、最適化された実装例を見てみよう。
/
- font-display: swap を指定して、まずはシステムフォントで見せる。
- さらに、preload を使うことで、ブラウザがCSSを解析し終える前に
- フォントのダウンロードを開始させ、FOUTの期間を極限まで短縮する。
/
@font-face {
font-family: ‘MyCustomFont’;
src: url(‘/fonts/my-font.woff2’) format(‘woff2’);
font-weight: 400;
font-style: normal;
/
- swap: Webフォントが読み込まれるまで代替フォントを表示し、
- 読み込み完了後に即座に差し替える。
/
font-display: swap;
}
そして、HTMLの `
` には以下を仕込む。
—
なぜ「レイアウトシフト」が起きるのか?
ここが一番の落とし穴だ。Webフォントに差し替わった瞬間、文字の「横幅」が微妙に変わる。すると、ブラウザは再レイアウト(リフロー)を行い、画面内の要素がガタガタと動く。これが CLS (Cumulative Layout Shift) という指標を悪化させ、SEOやUXを損なう原因になる。
現場のTips:
完全に防ぐのは難しいが、`font-size-adjust` や、フォントの横幅を極力合わせるようなフォールバックフォントの指定をCSSで行うことで、フォント差し替え時の「ズレ」を最小限に抑えることができる。
body {
/
- Webフォントが読み込まれる前後のサイズ差を縮めるために
- ローカルのフォント指定(フォールバック)を調整する
/
font-family: ‘MyCustomFont’, sans-serif;
}
—
最後に:エンジニアとしての矜持
Webブラウザのレンダリングは、魔法ではなく緻密なロジックの積み重ねだ。
「フォントを読み込む」という単純な作業一つとっても、裏側ではネットワークリクエスト、パース、レイアウト計算が複雑に絡み合っている。
「なんとなく動く」で満足せず、ブラウザが今どこで詰まっているのかをDevToolsの「Network」や「Performance」タブで眺めてみてほしい。フォントの読み込み時間を可視化できれば、君はもう一段上のフロントエンドエンジニアになれるはずだ。
困ったときは、ブラウザの気持ちになって考えてみてくれ。彼らは常に「最速でコンテンツを見せたい」と思っている。僕たちがその手助けをしてやるんだ。頑張れよ!

コメント