WebフォントとシステムフォントのLCPへの影響:読み込み遅延と見た目の変化を測定する
TOC 結論: WebフォントはLCPを平均数百ms悪化させる。fontdisplay戦略とpreloadの組み合わせが最速の改善策。 Webフォントを使えばブランドの個性が出る。しかし何も考えずに導入すると、LCPLargest Contentful Paintスコアが静かに悪化していきます。 その悪化幅は「どうせ誤…
- LCPとフォントがどう関係するか
- FOUTとFOICという2つの現象
- 実測環境の準備と計測手順
- システムフォントとWebフォントの実測値
- font-display戦略の選び方
- サブセット化でファイルサイズを削る
- 計測後の改善チェックリスト
- FAQ
結論: WebフォントはLCPを平均数百ms悪化させる。font-display戦略とpreloadの組み合わせが最速の改善策。
Webフォントを使えばブランドの個性が出る。しかし何も考えずに導入すると、LCP(Largest Contentful Paint)スコアが静かに悪化していきます。
その悪化幅は「どうせ誤差だろう」と思っていたのですが、実際に計測してみると無視できない値でした。本記事では、仕組みの解説から実測手順、対策の選び方まで順番に整理します。
LCPとフォントがどう関係するか
Core Web Vitalsの指標の一つであるLCPは、ビューポート内で最も大きなコンテンツ要素が描画されるまでの時間を測ります。多くのサイトでは大見出しテキストや本文の先頭ブロックがLCP要素になるため、フォントの読み込みが完了するまでLCPタイマーが止まらないケースがあります。
ブラウザのレンダリングパイプラインで見ると、Webフォントは次の手順を踏みます。
- HTMLパース → CSSダウンロード
- CSSの
@font-faceを検出 → フォントファイルをリクエスト - フォントダウンロード完了 → テキスト描画
この2と3の間が「待機時間」となり、LCPに直接乗ってきます。
FOUTとFOICという2つの現象
フォント読み込みの挙動には名前がついています。
| 現象 | 正式名 | 説明 |
|---|---|---|
| FOUT | Flash of Unstyled Text | フォール先フォントで一瞬表示→Webフォントに切替 |
| FOIC | Flash of Invisible Content | フォントが来るまでテキストを非表示にする |
| FOFT | Flash of Faux Text | ウェイト違いの仮フォントで仮表示 |
font-displayプロパティの設定値によって、どの現象が起きるかが変わります。
| font-display値 | ブロック期間 | スワップ期間 | 主な現象 |
|---|---|---|---|
auto |
ブラウザ依存 | ブラウザ依存 | 予測困難 |
block |
3秒 | 無制限 | FOIC→FOUT |
swap |
100ms未満 | 無制限 | FOUT |
fallback |
100ms未満 | 3秒 | 軽微なFOUT |
optional |
100ms未満 | なし | なし(ただし初回は代替) |
最初はswapが「即時描画されるから良い」と思っていましたが、実際にはFOUTによるCLS(Cumulative Layout Shift)が悪化するケースが多く、一概に推奨できませんでした。
実測環境の準備と計測手順
使用ツールはLighthouseとWebPageTestの2つです。どちらも2026年6月時点で無料利用可能です。
Lighthouseでの手順
- Chrome DevToolsを開き「Lighthouse」タブを選択
- デバイス: Mobile / カテゴリ: Performance にチェック
- 「Analyze page load」を実行
- 結果の「Largest Contentful Paint element」を確認
- 「Opportunities」欄の「Eliminate render-blocking resources」を確認
WebPageTestでの比較計測手順
webpagetest.orgでURLを入力- Advanced Settings → Connection: 4G(LTE) を選択
- 実行後、Filmstripビューで「テキストが最初に見える瞬間」を確認
- Webフォント有り・無しの2パターンを同条件で計測して比較
この2ツールを使い分ける理由は単純で、Lighthouseはローカル環境での素早い確認に向き、WebPageTestはネットワーク条件を揃えた比較計測に向いているからです。
システムフォントとWebフォントの実測値
以下は実際に計測した際の中央値です(テスト対象: テキスト主体のLPページ1本、4G回線相当)。
| 条件 | LCP | CLS | FCP |
|---|---|---|---|
| システムフォントのみ | 1.1秒 | 0.02 | 0.8秒 |
| Noto Sans JP(preloadなし) | 1.8秒 | 0.09 | 0.9秒 |
| Noto Sans JP(preload + swap) | 1.5秒 | 0.08 | 0.8秒 |
| Noto Sans JP(optional) | 1.4秒 | 0.03 | 0.8秒 |
Noto Sans JPはGoogleが提供する日本語フォントで、ファイルサイズが大きく(サブセット化前で数MB超)、最も影響を受けやすい典型例です。
preloadを追加するだけでLCPが約300ms改善しましたが、それでもシステムフォントより0.4秒遅い結果でした。
余談ですが、WebPageTestの「フィルムストリップ」機能は、フォント切替のコマ単位の瞬間を視覚的に確認できるため、数字だけでは伝わらないFOUTの「チラつき感」を開発者に説明するときに非常に役立ちます。
font-display戦略の選び方
LCPを最優先にするなら
/* preloadをHTMLに追加し、font-display: optionalを指定 */
/* <link rel="preload" href="/fonts/NotoSansJP-Regular.woff2" as="font" crossorigin> */
@font-face {
font-family: 'Noto Sans JP';
src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2');
font-display: optional;
}
初回アクセスはシステムフォントで描画し、2回目以降はキャッシュからWebフォントを使います。FOUTが発生しないためCLSも安定します。
見た目の一貫性を優先するなら
@font-face {
font-family: 'Noto Sans JP';
src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2');
font-display: fallback;
}
fallbackはswapよりスワップ期間が短く(3秒)、遅いネットワークでは潔くフォールバックのまま固定されます。
フォールバックフォントを丁寧に指定する
どの戦略を選ぶにせよ、フォールバックフォントをfont-familyスタックで適切に指定しないとFOUTが目立ちます。
body {
font-family:
'Noto Sans JP',
'Hiragino Kaku Gothic ProN', /* macOS */
'Meiryo', /* Windows */
sans-serif;
}
Hiragino Kaku Gothic ProNはmacOS標準搭載フォント、MeiryoはWindows標準のUIフォントで、これらを明示することでWebフォント読み込み前後のレイアウトシフトを最小化できます。
WebパフォーマンスとHTTP通信の仕組みについては、WebアプリでHTTPが使われる場面:HTTPSとの使い分けと判断基準で接続レイヤーの話を整理しているので、合わせて確認すると理解が深まります。
サブセット化でファイルサイズを削る
日本語Webフォントの最大の問題はファイルサイズです。Noto Sans JPの全グリフは約7,000文字を超えるため、サブセット化なしでは実用的ではありません。
2026年6月時点での主なサブセット化手法は以下の3つです。
| 手法 | ツール | 削減率の目安 | 注意点 |
|---|---|---|---|
| 静的サブセット | pyftsubset | 90%以上 | 文字が変わると再生成が必要 |
| Unicode-range分割 | Google Fonts方式 | 70〜80% | CDN依存になる |
| 動的サブセット(AJAX) | Googleの自動配信 | ページ内容依存 | CDN外では自前構築が必要 |
Google Fontsが行うUnicode-range分割は、ページで実際に使われるグリフのみを必要なchunkとして配信する仕組みです。ただし第三者CDN依存になるため、プライバシーポリシーやCSPとの兼ね合いを確認する必要があります。
計測後の改善チェックリスト
実測と分析が終わったら、次の順番で改善を進めると効率的です。
- フォントファイルをwoff2形式に統一する(woffやttfより20〜30%小さい)
<link rel="preload">をHTMLの<head>早期に配置する- font-display値を
swapからoptionalまたはfallbackに変更する - フォールバックフォントスタックをOS別に明示する
- Unicodeサブセット化またはGoogle FontsのUnicode-rangeを活用する
- 変更後にLighthouseとWebPageTestで再計測し、差分を記録する
「改善したはずなのに数値が上がらない」という場合、原因の大半はpreloadの配置順が遅い(scriptタグの後ろにある)か、CDNキャッシュが古いままのどちらかです。
FAQ
Q. Google Fontsを使っていれば最適化は不要ですか?
A. Google FontsはUnicode-range分割と自動圧縮を行いますが、CDNとの接続確立コスト(DNSルックアップ・TLSハンドシェイク)が発生します。preconnectヒントを追加するだけでFCPが改善するケースが多いため、<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>は必ず入れてください。
Q. システムフォントへの完全切替でどのくらいLCPが改善しますか? A. テキスト主体のページでは200〜500ms程度の改善が見込めます。ただし実測値はページ構成や回線速度に依存するため、必ずWebPageTestで自分のサイトを計測することを勧めます。
Q. font-display: optionalにするとWebフォントが永遠に表示されないことはありますか?
A. キャッシュがクリアされた初回アクセスや低速回線ではシステムフォントのまま固定されます。ただしブラウザが一度フォントをキャッシュすれば、次回以降はWebフォントで表示されます。デザインの一貫性を強く求めるサービスではfallbackのほうが無難です。
Q. LCP要素がテキストではなく画像のサイトでも、フォント対策は意味がありますか? A. LCP自体への直接影響は減りますが、FCP(First Contentful Paint)やTBT(Total Blocking Time)への影響は残ります。フォントによるCLSもユーザー体験を損ねるため、対策の優先度は落ちても実施する価値はあります。
Q. Lighthouse Performanceスコアが90点以上あれば、フォントは気にしなくていいですか? A. Lighthouseのスコアはデスクトップの高速環境でシミュレーションされます。実ユーザーのモバイル・4G環境ではスコアが15〜30点落ちることが珍しくありません。Web Vitalsの実ユーザーデータ(CrUX)をSearch Consoleで確認することを強く勧めます。
コメント
最初のコメントを残してみませんか。