独立サイトのフォント最適化:システムフォント、font-display、プリロードとFOIT

フォントは独立サイトで最も見落とされやすい性能の時限爆弾です。未最適化のWebフォントファイルは300KBから2MBになることが多く、読み込み中はブラウザが文字を非表示にします(FOIT)。3G回線ではファーストビューが3秒間空白になるのと同じです...

字体加载四态:FOIT、FOUT、swap与系统字体的取舍Font loading: FOIT vs FOUT vs swap vs system font stack 用Web字体会让首屏文字慢300至1000毫秒 —— B2B站真的值吗Web fonts delay text 300-1000ms — is it worth it on a B2B site 策略Strategy 首屏文字First-paint text 适用判断When to use 系统字体栈System stack 立即显示Instant 大多数B2B站默认选它Default for most B2B font-display:swapfont-display:swap 先fallback后替换Fallback then swap preload+swappreload + swap fallback后快速替换Fast swap after preload 品牌站首屏标题Brand hero headings font-display:blockfont-display:block 3秒内空白(FOIT)3s invisible (FOIT) 核心规则:自定义字体≤2个家族 · 每家族只加载400和700 · 子集化Rule: ≤2 families · weights 400+700 only · subset 中文Web字体几乎不可行 —— 一个中文字体2至8MB,系统字体栈是正确答案CN web fonts impractical (2-8MB) — use system stack 红线:字体文件没子集化就上全站 —— 中文一个文件5MB起步Red line: shipping unsubsetted CJK font (5MB+) font-display:block在3G下等于首屏3秒空白,访客早走了block on 3G = 3s blank screen, visitor already gone
フォント読み込み4戦略:システムフォント、swap、preload+swap、blockの比較

独立サイトのフォント最適化:システムフォント、font-display、プリロードとFOIT

結論から言うと:フォントは独立サイトで最も見落とされやすい性能の時限爆弾です。未最適化のWebフォントファイルは300KBから2MBになることが多く、読み込み中はブラウザが文字を非表示にします(FOIT)。3G回線ではファーストビューが3秒間空白になるのと同じです。正しい方法は3層に分かれます。英語サイトはWebフォントを最大2ファミリーまで、各ファミリーは400と700の2ウェイトのみ読み込み、font-display:swapを必須にします。中国語サイトはWebフォントをほぼ使わず、システムフォントスタックを直接使います。中国語フォントはサブセット化しても1ファイル2から8MB残るためです。直感に反する判断ですが、B2Bサイトで装飾的なカスタムフォントを使ってもコンバージョンにはほぼ効果がなく、むしろLCPを悪化させます。システムフォントスタックこそが既定の答えです。

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フォントを使うべき?
いいえ、システムフォントスタックがほとんどのB2Bサイトの正解です。B2Bのコンテンツは仕様、事例、技術記事が中心で、システムフォントで視覚的には十分ですし、ネットワークリクエストがゼロで即座に表示されます。GitHub、Stripe、Linearもシステムフォントスタックを使っています。ブランド感が特に重要で、ファーストビューの見出しにカスタムフォントが必要な場合だけ、Webフォントを1ファミリー読み込み、必ずswap+subset+preloadを設定します。
font-display:swapとblockの違いは?
blockはフォント読み込み中に文字を非表示にし(FOIT)、3秒後にfallbackを使います。swapはすぐにfallbackフォントで文字を表示し、Webフォントのダウンロード完了後に置き換えます。B2Bサイトでは必ずswapを使います。ユーザーが先に内容を読めることのほうが、飾り文字の見出しを待つことより重要なためです。blockは3G回線ではファーストビューが3秒間空白になるのと同じで、訪問者はすぐ離脱します。fallbackは折衷案で、100ms非表示にした後fallbackを使い、3秒以内に読み込みが完了すれば置き換えます。
日本語フォントはWeb Fontとして使える?
ほぼ推奨しません。日本語・中国語フォントのファイルは2〜8MB、サブセット化しても200KB〜1MB残り、ファーストビューの予算を大きく超えます。サブセット化しても、ユーザーがページをめくった先にサブセット外の文字があれば再読み込みが必要です。正しい方法はシステムフォントスタックを使うことです。macOSならPingFang SC、WindowsならMicrosoft YaHei、AndroidならNoto Sans CJK。プラットフォームをまたいで表示が揃い、ダウンロードはゼロです。画像にするのはブランドロゴだけにして、本文はすべてシステムフォントで組んでください。
preloadでフォントを読み込むとき、なぜcrossoriginが必要なのですか?
フォントファイルの取得はCORSリクエストにあたるため、同一オリジンでもcrossorigin属性が必須です。付けなければpreloadはダウンロードするものの@font-faceでは使われず、無駄になります。正しい書き方はlink rel=preload as=font type=font/woff2 href=… crossoriginです。crossoriginの付け忘れはpreloadが効かない最も多い原因で、Lighthouseは「プリロードされたリソースが使用されていません」と指摘します。
Google Fontsを最速で読み込むには?
手順は3つです。1つ目、URLにdisplay=swapパラメータを付ける。2つ目、ウェイトは400と700の2つだけを要求し、全ウェイトは要求しない。3つ目、フォントファイルはセルフホストし、fonts.googleapis.comは参照しない。Google Fontsのドメインは国内や一部の欧米企業ネットワークでブロックされたり遅くなったりするためです。セルフホストにすれば自社のCDN経由になり、DNSハンドシェイクも1回節約できます。Google Webfonts Helperでwoff2をローカルにダウンロードすれば済みます。
フォント最適化はどう検収すればいいですか?
DevToolsのNetworkでFontを絞り込み、3点を見ます。フォントファイルが2ファミリー以内、1ファイルが50KB以内、ファーストビューのフォントが最初のリクエストに含まれていること。CSSを確認し、font-displayがすべてswapで、ttf/eotのような旧形式がないこと。Lighthouseでは「レイアウトシフトを避ける」と「重要なリクエストをプリロードする」の2つのauditがすべて緑かを見ます。最後にCrUXでLCPの75パーセンタイルが2.5秒以内かを確認します。それでもLCPが遅い場合は、Performanceパネルでフォントがブロックしていないかを見てください。

六、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秒でユーザーを引きつけられるかを決めます。

环形山
环形山 クレーター専門家

公式アカウント · 環形山 Crater

環形山(Crater)は、WordPress独立サイト開発+Google SEO+GEO全域成長に特化した海外展開支援会社で、スマートハードウェア、産業機器、SaaS、新エネルギーなどの分野を手がけています。

プロダクト能力方法論ホワイトペーパー業界レポート
965件のシェア
78件のナレッジベース