font-displayとWebフォント最適化|Core Web Vitalsを改善する実践ガイド
Webフォントがパフォーマンスに与える影響
Webフォント(Google Fonts、Adobe Fontsなど)はサイトのデザイン品質を高める一方で、適切に設定しないとCore Web Vitalsのスコアを大きく悪化させる原因になります。
主な影響は2つです。
- LCP(Largest Contentful Paint)の悪化:フォントファイルの読み込みが遅いと、テキストの表示がブロックされ、最大コンテンツの描画が遅延する
- CLS(Cumulative Layout Shift)の悪化:フォント切り替え時にテキストサイズが変わり、レイアウトがずれる
これらの問題は font-display プロパティの正しい設定で大幅に改善できます。
font-displayとは
font-display は、Webフォントの読み込み中にブラウザがどのようにテキストを表示するかを制御するCSSプロパティです。
@font-face {
font-family: 'Noto Sans JP';
src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2');
font-display: swap;
}
font-displayの5つの値
| 値 | 動作 | LCPへの影響 | CLSへの影響 |
|---|---|---|---|
auto | ブラウザのデフォルト動作(多くの場合blockと同じ) | 悪い | 低い |
block | フォント読み込みまで非表示(最大3秒) | 悪い | 低い |
swap | 代替フォントで即表示→読み込み後に切り替え | 良い | やや高い |
fallback | 100msだけ非表示→代替表示→短時間で切り替え | 良い | 低い |
optional | 100msだけ非表示→間に合えば使用、間に合わなければ代替のまま | 最良 | 最低 |
Googleが推奨する設定
Googleは**font-display: swap** を推奨しています。PageSpeed InsightsやLighthouseでも「Ensure text remains visible during webfont load」という警告でswapの使用が促されます。
swapのメリットは、フォント読み込み前でもテキストが即座に表示されること。これによりLCPが大幅に改善します。テキストが最大コンテンツ要素であるページ(ほとんどのブログやコーポレートサイト)では特に効果的です。
ただし、代替フォントからWebフォントへの切り替え時にテキストサイズが変わるため、わずかなCLSが発生する可能性があります。これは後述するsize-adjustで軽減できます。
Google Fontsの最適な読み込み方
基本:display=swapパラメータを追加
Google FontsのURLに&display=swapを追加するだけで、font-display: swapが適用されます。
<!-- NG: display指定なし -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700" rel="stylesheet">
<!-- OK: display=swap を追加 -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
高速化:preconnectの追加
Google Fontsのドメインへの接続を事前に確立することで、フォントの読み込み開始が早くなります。
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
最速:セルフホスティング
フォントファイルを自サーバーに配置する方法が最もパフォーマンスに優れます。外部ドメインへのリクエストが不要になり、キャッシュ制御も自在です。
@font-face {
font-family: 'Noto Sans JP';
src: url('/fonts/NotoSansJP-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
Next.jsではnext/fontを使うことで、ビルド時にフォントが自動的にセルフホスティングされ、最適なfont-display設定も適用されます。
import { Noto_Sans_JP } from 'next/font/google';
const notoSansJP = Noto_Sans_JP({
subsets: ['latin'],
weight: ['400', '700'],
display: 'swap',
});
CLSを防ぐ:size-adjustによるフォントマッチング
font-display: swapを使うと、代替フォントからWebフォントへの切り替え時にCLSが発生することがあります。これは2つのフォントの文字幅や高さが異なるためです。
size-adjustプロパティで代替フォントのサイズを調整し、Webフォントとの差を最小化できます。
@font-face {
font-family: 'Adjusted Arial';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: 'Noto Sans JP', 'Adjusted Arial', sans-serif;
}
手動で値を計算するのは大変ですが、以下のツールが自動計算してくれます。
- Fontaine — Next.js/Nuxtと統合可能なライブラリ
- next/font — Next.jsの組み込みフォント機能が自動で
size-adjustを適用
読み込むフォントウェイトを最小限に
不要なフォントウェイトを読み込むと、その分だけダウンロードサイズが増えLCPが悪化します。
<!-- NG: 使わないウェイトまで読み込んでいる -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<!-- OK: 必要なウェイトだけ指定 -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
目安: ほとんどのサイトでは2〜3ウェイト(Regular + Bold、必要に応じてMedium)で十分です。
改善効果の確認方法
フォント最適化の効果は以下のツールで確認できます。
- PageSpeed Insights — LCPとCLSのスコアを確認。「Ensure text remains visible during webfont load」の警告が消えたかチェック
- Chrome DevTools > Performance — フォント読み込みのタイムラインを可視化
- Chrome DevTools > Network — フォントファイルのサイズと読み込み時間を確認
- IndexReady — URLを入力するだけでCore Web Vitalsスコアとパフォーマンス項目を自動採点
よくある質問
font-display: swapとoptionalどちらが良いですか?
ブランドフォントの表示を重視するならswap、パフォーマンスを最優先するならoptionalが適しています。optionalはネットワークが遅い場合にWebフォントを使わない判断をするため、CLSはゼロになりますが、フォントが表示されない可能性があります。多くのサイトではswapが最もバランスの良い選択です。
next/fontを使えばfont-displayの設定は不要ですか?
next/fontはデフォルトでfont-display: swapを適用し、セルフホスティングも自動で行います。さらにsize-adjustの自動計算によりCLSも最小化されるため、Next.jsプロジェクトではnext/fontの使用が最も簡単で効果的です。
日本語フォントは英語フォントより重いですか?
はい、日本語フォントは文字数が圧倒的に多いため、ファイルサイズが英語フォントの10〜20倍になることがあります。Google Fontsの日本語フォントはサブセット分割されていますが、それでもウェイト数を最小限に抑えることが重要です。
プリロード(preload)すべきですか?
ファーストビューに表示される重要なフォントにはpreloadが効果的です。ただし、使わないフォントをpreloadすると逆に帯域を圧迫するため、必要なフォントだけに限定してください。
<link rel="preload" href="/fonts/NotoSansJP-Regular.woff2" as="font" type="font/woff2" crossorigin>