独立サイトのフォント最適化:システムフォント、font-display、プリロードとFOIT
1. フォントが文字表示をブロックする理由
ブラウザはフォントファイルを取得するまで文字がどう表示されるべきか分かりません。既定の動作は文字を非表示にすることです(FOIT、Flash of Invisible Text)。この非表示期間は旧ブラウザでは3秒、新ブラウザでは1秒後にフォールバックフォントで強制表示に変わります。問題は、ファーストビューの本文がまさにLCP要素であり、それがフォントを待っているとLCPがフォントのダウンロード時間に引きずられることです。
独立サイトでありがちなミス:テーマ作者が「デザイン性」のためにGoogle FontsのInterやRobotoの全ウェイト(100から900の9ウェイト)を読み込み、各ウェイト100KBで一度に900KBを読み込んでしまいます。3G回線ではフォントだけで3から5秒かかり、ユーザーには真っ白な画面が見えます。Core Web Vitalsのフォント関連指標はCore Web Vitalsの最適化、CDNの設定はCDNグローバル高速化。
| 問題 | 性能への影響 | 典型的なサイズ |
|---|---|---|
| 全ウェイト(9段階)を読み込み | ファーストビューで800KB余分にダウンロード | 1ウェイトあたり80から120KB |
| サブセット化していない中国語フォント | 1ファイル2から8MB | ファーストビューの予算を大幅に超過 |
| font-displayの既定値block | FOITで1から3秒非表示 | 文字が見えない |
| 重要なフォントをpreloadしていない | フォントの発見が遅れ、200msの遅延 | LCPが遅くなる |
| 複数ファミリー(3つ以上)を使用 | 各ファミリーをダウンロード | 累計300から500KB |
2. システムフォントスタック:B2Bサイトの既定の答え
システムフォントスタックはユーザーのデバイスにすでにインストールされているフォントを使うため、ネットワークリクエストがゼロで即座に表示されます。B2B独立サイトのコンテンツは仕様表、事例紹介、技術記事が中心で、レイアウトに装飾的なフォントやブランド専用フォントは必要ありません。システムフォントスタックで視覚的には十分であり、クロスプラットフォームでも一貫しています。
すぐ使えるCSSスタック: font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, “Helvetica Neue”, Arial, “PingFang SC”, “Microsoft YaHei”, sans-serif。このスタックはmacOS、Windows、Android、iOSをカバーし、日本語・英語それぞれに対応するシステムフォントがあります。直感に反する判断:システムフォントを使ってもサイトが”素人っぽく”見えることはない。むしろGitHub、Stripe、Linearといったデザインの基準となるサイトがシステムフォントスタックを採用しています。WPテーマの選び方はWordPress技術スタック。
| プラン | ファーストビューのテキスト | 追加ダウンロード | 向いているサイト |
|---|---|---|---|
| システムフォントのみ | 即時表示 | 0KB | ほとんどのB2B自社サイト |
| Webフォント見出し1つ | fallback後に置換 | 30至80KB | ブランド感を強調したいサイト |
| Webフォント2ファミリー | fallback後に置換 | 80至150KB | デザイン重視のブランドサイト |
| Webフォント3つ以上 | FOUT/FOITが目立つ | >200KB | 推奨しない |
| 日本語Webフォント全量 | FOITが数秒 | 2至8MB | ほぼ不可能 |
三、font-display:swapとFOIT: 文字を隠さない
font-displayは@font-face内のプロパティで、フォント読み込み中の文字表示を制御します。値は4つ: auto(ブラウザ既定、以前はblock)、block(3秒間非表示にしてからfallback)、swap(すぐfallbackで表示し、フォントが読み込めたら置換)、optional(ブラウザが判断し、ダウンロードしない方向に傾く)。
B2B自社サイトは一律swapにすべきです。blockは3G回線ではファーストビューが3秒間空白になるのと同じで、訪問者はとっくに離脱しています。optionalはブランド上重要でないフォント向けですが、制御できません。よくある誤解は”swapはフォントのちらつき(FOUT)を起こす”というものですが、B2Bサイトではユーザーに仕様や連絡先を先に読んでもらうほうが、飾り文字の見出しを待たせるよりはるかに重要です。フォントが一瞬ちらつくのは十分許容できますが、文字が見えないのは本当の損失です。CSS/JSの読み込み戦略はCSS/JS最適化。
| font-display | ブロック期間 | フォント読み込み後 | 適用シーン |
|---|---|---|---|
| auto/block | 3秒間文字が見えない | Webフォントに置換 | 推奨しない |
| swap | すぐfallbackで表示 | フォントが読み込めたら置換 | B2Bサイトの既定 |
| fallback | 100ms非表示、その後fallback | 3秒以内に読み込めた場合のみ置換 | 準重要なフォント |
| optional | 100ms非表示、その後fallback | 今回の訪問では置換しない | 純粋な装飾フォント |
四、preloadとサブセット化: 速くすべきフォントを速くする
ファーストビューの見出しにどうしてもWebフォントを使うなら、preloadでブラウザに優先ダウンロードを指示します。head内に<link rel=”preload” href=”font.woff2″ as=”font” type=”font/woff2″ crossorigin>を追加します。これでフォントがCSS解析より前にダウンロードを開始し、LCPを200〜400ミリ秒早められます。crossorigin属性は省略できない点に注意してください。省略するとpreloadが効きません。
サブセット化(subset)も必ず行う最適化です。英字フォントは英字+数字+よく使う記号だけを残し、容量を100KBから30KBに圧縮できます。一方、日本語フォントは文字セットが大きすぎて、サブセット化しても200KBから1MBになるため、日本語サイトではシステムフォントを直接使うのがおすすめです。glyphhangerやGoogle Fontsのtextパラメータを使って、実際に使う文字だけを読み込みます。具体例として、ファーストビューの見出しに20文字しか使わないなら、その20文字だけをサブセット化し、ファイルを4MBから5KBに圧縮できます。CDNキャッシュはこちらCDN選定比較。
| フォント最適化の施策 | 容量・遅延の効果 | 実施の難易度 | おすすめ |
|---|---|---|---|
| woff2形式のみ使用 | ttfより30%小さい | 低 | 必須 |
| ウェイトは400と700のみ読み込み | ダウンロード量を60%削減 | 低 | 必須 |
| 英字文字セットをサブセット化 | さらに50%削減 | 中 | 推奨 |
| ファーストビューのフォントをpreload | LCPが200〜400ms早まる | 低 | ファーストビューの見出しに |
| 日本語の全量Webフォント | 非推奨 | 高 | やってはいけない |
5. 検証:DevToolsでフォント読み込みのウォーターフォールを確認
フォント最適化が終わったら、どう検証するのでしょうか。Chrome DevToolsのNetworkパネルを開き、Fontでフィルタして3つを確認します。フォントファイルの数(2ファミリー以下、各ファミリー2ウェイト以下が望ましい)、フォントファイルのサイズ(1つ50KB以下が健全)、フォントのダウンロード開始タイミング(preload後はCSS解析後に発見されるのではなく、最初のリクエストに含まれるべき)です。どれか1つのフォントファイルが100KBを超えていたら、ウェイトやサブセットの設定が正しいか確認しましょう。
さらにLighthouseで「Webフォントのレイアウトシフトを回避する」と「重要なリクエストをプリロードする」の2つの監査項目を確認します。実行可能なチェックリストは、font-displayがすべてswap、ファーストビューのフォントをpreload、woff2形式、ttf・eotの旧形式なし、Google Fontsはdisplay=swapパラメータを使用、です。多言語サイトのフォントの扱いはこちら多言語サイトのグラフ処理。サイト監視はこちらサイト監視アラート。
| 検証項目 | 合格基準 | 計測ツール |
|---|---|---|
| font-display | すべてswapまたはfallback | CSSレビュー |
| ファーストビューのフォントをpreload | ファーストビュー見出しのフォントをpreload済み | DevTools Network |
| フォントファイル形式 | woff2のみ | NetworkでFontをフィルタ |
| 1フォントあたりの容量 | 50KB以下 | NetworkのSize列 |
| フォントファミリー数 | 2つ以下 | CSSレビュー |
| LCP 75パーセンタイル | 2.5秒以下 | CrUX/RUM |
FAQ よくある質問
B2Bの独立系サイトは必ずWebフォントを使うべき?
font-display:swapとblockの違いは?
日本語フォントはWeb Fontとして使える?
preloadでフォントを読み込むとき、なぜcrossoriginが必要なのですか?
Google Fontsを最速で読み込むには?
フォント最適化はどう検収すればいいですか?
六、FOUTとレイアウトシフト:フォント切り替え時に画面を揺らさない方法
swap戦略を使うと、フォールバックフォントからWebフォントに切り替わる際、文字幅や行高の違いでページが動くことがあります。これがCLS(累積レイアウトシフト)の発生源です。Stripeの計測では、フォント切り替え1回あたり平均0.05〜0.1のCLSが発生し、合格ラインの0.1ぎりぎりに収まっていました。B2Bサイトは本文が長く段落も多いため、切り替えによる改行位置のずれで画像の位置が上下に動きます。
対処法はfont-size-adjustとsize-adjustの2つの記述子です。@font-face内でsize-adjust: 105%とascent-overrideを使い、Webフォントのメトリクスをフォールバックに近づけておけば、切り替え時にもほとんど動きません。もう一つのもっと手軽な方法は、フォールバックフォントとWebフォントのメトリクスが近い組み合わせを選ぶことです。たとえばInterのフォールバックにArialを選ぶ、あるいはシステムフォントスタックをそのまま使って切り替えない、といった具合です。具体的な検収としては、Lighthouseの「Webフォントでのレイアウトシフトを避ける」auditを見て、スコアが低ければまずswapが原因かを確認し、そのうえでsize-adjustを足すか判断します。
| FOUTの対処方法 | CLS改善 | 実施の難易度 |
|---|---|---|
| 対策せず、ちらつきを受け入れる | 0.05至0.1 | なし |
| size-adjustで微調整 | 0.02以下に下げる | 中程度、要検証 |
| メトリクスが近いフォールバックを選ぶ | 0.03以下に下げる | 低 |
| Webフォントを使わない | 0 | コストゼロ |
最後に
フォント最適化の判断はシンプルです。B2Bサイトのユーザーはスペックを読み、事例を見て、連絡先を探しに来るのであって、タイポグラフィを鑑賞しに来るわけではありません。システムフォントスタックが95%のケースで正解であり、削減できる数百KBと数百ミリ秒は、見た目の違いよりはるかに重要です。Webフォントを残す場合でも、2ファミリー、2ウェイト、woff2形式、swap読み込みの4条件を厳守してください。
実行は3ステップです。第一に、今週中にテーマのフォントをシステムフォントスタックに変更し、不要なGoogle Fontsの参照を削除します。第二に、残すWebフォントにはすべてfont-display:swapを設定し、ウェイトは400と700のみに絞り、woff2ファイルをセルフホストします。第三に、ファーストビューの見出しフォントにpreloadを設定し、crossoriginも追加します。2週間後にLCPとフォント関連のauditが改善したか確認しましょう。
覚えておきたい一言。ユーザーはInterを使っているからといって1秒長く滞在することはありませんが、フォントの読み込みを3秒待たされたらすぐに閉じます。フォントは細部ですが、その細部がファーストビューの2.5秒でユーザーを引きつけられるかを決めます。
