「ウェブフォントの読み込み中もテキストが表示されたままにする」の修正
Webfontsは使用前にダウンロードする必要があります。そのため、読み込み中はテキストが一時的に非表示になります。
「Ensure text remains visible during webfont load」の概要
ウェブフォントは、ウェブブラウザでデフォルトでは使用できないフォントです。そのため、使用する前にダウンロードする必要があります。ウェブフォントのダウンロード中、読み込みが完了するまでウェブページ上のテキストは一時的に非表示になります。
その結果、訪問者が利用できる状態になるまでページの読み込みが「完了」しないため、ページの読み込み速度が大幅に遅く感じられます。これはUXの低下につながる可能性があります。ページに対してLighthouseの分析を実行すると、ページの読み込みパフォーマンスに関する警告が表示されます。「Ensure text remains visible during webfont load」です。
これを解決するには、font-displayの値を変更するか、フォントローダーを使用します。この記事では、その仕組みについて解説します。
Arjen Karelによる最終査読:2026年2月
ウェブフォントの読み込み中もテキストが表示されたままになるようにする
ウェブフォントが登場する前、ウェブデザイナーはあらかじめインストールされている少数のフォントしか使えませんでした。ウェブフォントは、ウェブサイト上で任意のフォントを自由に使うことを可能にします。
もちろん、それは魅力的に聞こえますが、ウェブフォントにはデメリットもあります。さまざまな形でページの読み込み速度を低下させます。
ウェブフォントは通常、デフォルトではコンピュータにインストールされていない大容量ファイルです。そのため、使用する前にダウンロードする必要があります。ウェブフォントのダウンロード中、ウェブフォントの読み込みが完全に完了するまで、ウェブページ上のテキストは一時的に非表示になります。これはUXの低下を招きます。真っ白な画面を長く見つめたい人はいません。
ウェブフォントが読み込まれてレンダリングされるとすぐに、ブラウザは「非表示のテキスト」を新しいウェブフォントによる最終的なテキストに置き換えます。この瞬間をFlash of Invisible Text(FOIT)と呼びます。このFOITが、「Ensure text remains visible during webfont load」というエラーメッセージが表示される原因です。

ウェブフォントをページに読み込む際、このFlash of Invisible Textを防ぐ対策を何も行っていないと、LighthouseでPageSpeedを分析するときに次のメッセージが表示されます。「Ensure text remains visible during webfont load」です。これは、ウェブフォントが読み込まれる前にテキストを表示させることで、どれだけの時間を節約できるかを示しています。フォントが1つだけでも、100msは簡単に短縮できます。
なぜテキストの非表示はページの読み込み速度に悪影響を与えるのか?
テキストが非表示になっていても、最終的な測定上のページの読み込み時間は実際には遅くなりません。では、なぜLighthouseはこれを問題視するのでしょうか。
Googleは、ウェブページができる限り最高のUXを提供することが重要だと考えています。ページ上のコンテンツをできるだけ早く表示することで、UXを向上させることができます。テキストが非表示であると、ブラウザは非表示의テキストを描画できないため、First Contentful Paint (FCP)に直接悪影響を及ぼします。もしテキストがLargest Contentful Paint (LCP)の要素である場合、FOITはその指標も遅らせます。私たちのホームページの2つのフィルムストリップ版を以下で比較してみてください:
Flash of Invisible Text(テキスト非表示あり)
display:swapによる対策(テキスト非表示なし)
ご覧の通り、2つのページはまったく同じタイミングで読み込みが完了しています。それでも、対策後のウェブサイトの方が訪問者にとって見栄えがはるかに優れています。訪問者はすぐに文章を読み始めることができます。
だからこそ、最終的なフォントではなく「fallback」フォントであっても、とにかくテキストを表示させることが賢明なのです。これにより、訪問者はページが非常に速く読み込まれていると感じます。
簡単なまとめ:FOITとFOUT
本題に入る前に、FOITとFOUTという概念を整理しておきましょう。FOITは「Flash of Invisible Text」の略で、読み込み中にウェブフォントが表示されない現象を指します。これは、fallbackフォントを指定することで軽減できます。そして、fallbackフォントがウェブフォントに置き換わる現象を、FOUT(Flash of Unstyled Text)と呼びます。
読み込み中もウェブフォントを表示させる
フォントの読み込み中もテキストを表示させるには、2つの方法があります。1つ目はCSSのfont-displayの値を使用する方法、2つ目はクラスを介してfallbackフォントを使用する方法です。どちらの方法にもメリットとデメリットがあります。以下で詳しく解説します。
方法1:Font-display:swap
font-displayは、すべてのモダンブラウザで利用可能なCSS記述子(descriptor)です。font-display記述子は、フォントがダウンロードされたかどうか、またいつダウンロードされたかに基づいて、フォントの表示方法を決定します。font-displayは@font-faceルール内で使用します。
知っておくべき4つのfont-display値があります。
- swap:即座にfallbackフォントを表示し、ウェブフォントの読み込みが完了した時点でウェブフォントに切り替えます。切り替え可能な期間(swap window)は無制限であるため、最終的には必ずウェブフォントに置き換わります。ブランドフォントや見出しに最適です。
- optional:即座にfallbackフォントを表示します。接続速度に基づいて切り替えを行うかどうかはブラウザが判断します。切り替えが発生しないということは、レイアウトシフトがゼロになることを意味します。パフォーマンスを最優先する本文テキストに最適です。
- fallback:即座にfallbackフォントを表示し、ウェブフォントの読み込みに短い猶予期間(約3秒)を与えます。この期間内に読み込めなかった場合、fallbackフォントが表示され続けます。swapとoptionalの中間に位置する選択肢です。
- block:フォントが読み込まれるまでの間、最大3秒間テキストを非表示にします。これがFOITの原因です。特別な理由(アイコンフォントなど)がない限り、使用しないでください。
2025 Web Almanacによると、font-display: swapを使用しているサイトはわずか50%であり、25%は依然としてblockを使用しています。つまり、ウェブの4分の1で、フォントの読み込み中にテキストが非表示になったままになっていることになります。
FOITを回避し、できるだけ早く画面にテキストを表示させるには、swap値を使用します。@font-faceルールにfont-display: swap値を設定すると、ページ読み込み中、ウェブフォントの読み込みが完了するまでシステムのデフォルトフォントが使用されます。これにより、訪問者はすぐにページ上のテキストを読むことができます。
Google Fonts
Google Fontsを使用する場合、スタイルシートまたは埋め込みコードに「&display=swap」を追加するだけで、font-display: swapを適用できます。
<!-- 外部スタイルシート経由 --> <link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<!-- importメソッド経由(遅いため非推奨) -->
<style>
@import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap');
</style>
@importメソッドはrender blockingであり、ブラウザにスタイルシートを順番にダウンロードさせます。<link>メソッドの方が高速です。ブラウザが解析プロセスの早い段階でフォントのスタイルシートを見つけることができるからです。
しかし、私たちはどちらの方法もお勧めしません。ほぼ間違いなく、ウェブフォントをセルフホストする方がはるかに高速だからです。これにより、フォントの「プリロード(preload)」プロセスをより細かく制御できます。すでに確立されているHTTP/2接続を利用できるため、余分なスタイルシートをダウンロードする必要がありません。
Local fonts
@font-face {
font-family: "Open Sans";
font-weight: 400;
font-style: normal;
src: url("OpenSans400.woff2") format("woff2");
font-display: swap
}
必要なのはWOFF2だけです。すべてのモダンブラウザでサポートされており、最高の圧縮率を提供します。2025 Web Almanacによると、現在72%のサイトがフォントをセルフホストしており、WOFF2は全ウェブフォントリクエストの65%を占めています。もはやfallbackフォーマットとしてWOFFやTTFを含める理由はありません。
Prevent layout shift when swapping fonts
font-display: swapには落とし穴があります。ブラウザがfallbackフォントからウェブフォントに切り替える際、多くの場合、テキストのサイズが変化します。フォントによって文字幅、アセントの高さ(ascent height)、行間などが異なるためです。このサイズの変化が、Core Web Vitalsの指標であるCumulative Layout Shift (CLS)を引き起こします。
解決策は、CSSのsize-adjust記述子です。これは、ウェブフォントの寸法に合わせてfallbackフォントを拡大縮小し、切り替え時の視覚的なズレをほとんど、あるいはまったく発生させないようにします。ブラウザのサポート率はSafari 17+を含めて93%を超えています。
/* 適合するfallbackフォントの定義 */
@font-face {
font-family: "Open Sans Fallback";
src: local("Arial");
size-adjust: 105%;
ascent-override: 110%;
descent-override: 25%;
line-gap-override: 0%;
}
/* フォントスタックで両方を指定 */
body {
font-family: "Open Sans", "Open Sans Fallback", sans-serif;
}
ascent-override、descent-override、line-gap-overrideといった記述子を使用すると、垂直方向のメトリクスをさらに精密に制御できます。これらはChrome、Firefox、Edgeで動作しますが、Safariではまだサポートされていないため、プログレッシブエンハンスメントとして扱ってください。size-adjustプロパティだけでも、すでに顕著な違いが現れます。
CoreDashで監視されているサイト全体において、font-display: swapとフォントメトリクスのオーバーライドを組み合わせたページは、swap単体を使用しているページと比較して、フォント関連のCLSが75%少なくなっています。
方法2:クラスによるフォント制御
読み込み中もフォントを表示させる2つ目の方法は、クラスを利用することです。これらのクラスは通常、<body>または<html>要素に追加されます(必須ではありません)。
この方法のメリットは、fallbackフォントとFlash of Unstyled Textが発生するタイミングをより細かく制御できる点にあります。
具体的な仕組みは次の通りです。まずスタイルシートで、ページが最初に特定のフォント(fallbackフォント)でレンダリングされるように指定します。その後、JavaScriptのFontFace APIまたはプリロードを介してウェブフォントを読み込みます。フォントの読み込みが完了したら、ページにクラスを追加します。このクラスによってウェブフォントが有効化されます。
なぜそのようなことをするのか疑問に思われるかもしれません。それは、fallbackフォントをより詳細に制御するためです。fallbackフォントの行間を広くしたり、サイズを変更したりしてウェブフォントとより正確にマッチさせることで、レイアウトシフトを防ぐことができます。
複数のウェブフォントを使用する場合、FontFace APIを使用してすべてのフォントを一括で切り替えることができます。これにより、ブラウザの再描画(repaint)回数を大幅に削減できます。個人的にはこの方法はあまり好みません。最後のフォントが読み込まれるまでFOUTが発生しないため、どうしても必要以上に遅くなってしまうからです。
FontFace APIを使用したクラスによるフォント指定:
<style>
// 0.9remのフォントサイズを持つfallbackフォント
html{
font-family: sans-serif;
font-size:.9rem;
}
// 1remのフォントサイズを持つウェブフォント
html.fl{
font-family: 'webfont';
font-size:1rem;
}
</style>
<script>
var font = new FontFace("webfont", "url(/font.woff2)", {
style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});
// レンダリングツリーを待たず、即座にフェッチを開始します!
font.load().then(function() {
document.fonts.add(font);
document.documentElement.classList.add("fl")
});
</script>
プリロードリンク経由:
2つ目の方法は、プリロードリンクを使用する方法です。以下に示すように、フォントをプリロードします。プリロード完了後、<html>要素のクラスを切り替えます。
<link
rel="preload"
href="/webfont.woff2"
as="font"
type="font/woff2" crossorigin
onload="document.documentElement.classList.add('fl')">
<style>
// 0.9remのフォントサイズを持つfallbackフォント
html{
font-family: sans-serif;
font-size:.9rem;
}
// 1remのフォントサイズを持つウェブフォント
html.fl{
font-family: 'webfont';
font-size:1rem;
}
// htmlタグに.flクラスが追加された後にのみ有効化される@font-face
@font-face{
font-family:'Open Sans';
font-style:normal;
font-weight:400;
font-display:swap;
src: url(/webfont.woff2) format("woff2");
unicode-range:U+000-00FF;
}
</style>
追加のヒントとテクニック
- 画面に表示されるフォントは常にプリロードしてください。フォントは、ページ上で実際に使用されるまでデフォルトではダウンロードされません。ウェブフォントが必要な場合は、より早く利用できるようにプリロードしておきます。
- FOITとFOUTを完全に回避したいですか? その場合は、プリロードとfont-display: optionalを組み合わせて使用します。
- ウェブフォントをセルフホストする方が、Google Fontsや他の外部CDNを経由するよりも常に高速です。
フォントの読み込み戦略が実際にUXを向上させているか確認したいですか? その場合は、Real User Monitoringを使用して、変更前後のFCPとCLSを追跡してください。
何が本当に遅いのか、見つけ出します。
フィールドデータでCritical Rendering Pathをマッピング。Lighthouseレポートではなく、優先順位付きの修正リストをお渡しします。
監査を依頼する