Lighthouse の「Ensure text remains visible during webfont load」を解決する方法

「Ensure text remains visible during webfont load」の概要
ウェブフォントとは、ウェブブラウザでデフォルトでは使用できないフォントのことです。ウェブフォントは使用前にダウンロードする必要があります。ウェブフォントのダウンロード中、ウェブページ上のテキストはウェブフォントの読み込みが完了するまで一時的に非表示になります。
その結果、訪問者にとってページの「読み込みが完了していない」ように見えるため、ページの読み込みが非常に遅く感じられます。これは user experience の低下につながる可能性があります。Lighthouse でページを分析すると、ページの読み込みパフォーマンスに関する警告が表示されます:「Ensure text remains visible during webfont load」。
これは font-display の値を変更するか、フォントローダーを使用することで解決できます。この記事でその方法を説明します。

ウェブフォントの読み込み中にテキストを表示し続ける方法
ウェブフォントが登場する前、ウェブデザイナーはプリインストールされた少数のフォントしか使えませんでした。ウェブフォントにより、ウェブサイトで好きなフォントを自由に使えるようになりました。
もちろんそれは素晴らしいことですが、ウェブフォントにはデメリットもあります。いくつかの点でページの読み込み速度を低下させます。
ウェブフォントは通常、コンピュータにデフォルトでインストールされていない大きなファイルです。そのため、ウェブフォントは使用前にダウンロードする必要があります。ウェブフォントのダウンロード中、ウェブページ上のテキストはウェブフォントの読み込みが完全に完了するまで一時的に非表示になります。これは user experience を損ないます。誰も空白の画面を長時間見つめたくはありません。
ウェブフォントが読み込まれてレンダリングされると、ブラウザは「非表示のテキスト」を新しいウェブフォントの最終テキストに置き換えます。この瞬間を 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 は、ウェブページが可能な限り最高の user experience を提供することが重要だと考えています。ページ上のコンテンツをできるだけ早く表示することで、user experience を向上させることができます。以下の当サイトのホームページの2つのフィルムストリップ版を比較してください:
Flash of Invisible Text
display:swap で Flash of Invisible Text なし
ご覧の通り、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 ディスクリプタです。font-display ディスクリプタは、フォントがダウンロードされたかどうか、いつダウンロードされたかに基づいてフォントの表示方法を決定します。font-display は @font-face ルール内で使用します。
font-display にはさまざまな値があります:block、swap、fallback、optional。FOIT を回避し、テキストをできるだけ早く画面に表示するには、swap 値を使用します。
@font-face ルールで font-display: swap 値を設定すると、ウェブフォントが読み込まれるまでの間、システムのデフォルトフォントが使用されます。これにより、訪問者はページ上のテキストをすぐに読むことができます。
Google fonts
Google fonts を使用する場合、スタイルシートや埋め込みコードに「&display=swap」を追加するだけで font-display: swap メソッドを使用できます。
<!-- via een extern stylesheet -->
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet"> <!-- via de import methode -->
<style>
@import url ('https://fonts.googleapis.com/css?family=Open+Sans&display=swap);
</style>
ちなみに、私たちは Google fonts のファンではありません。ウェブフォントを自分でホストする方がほぼ常に高速です。フォントの「プリロード」プロセスをより細かく制御でき、既存の http/2 接続を使用でき、追加のスタイルシートをダウンロードする必要もありません。
ローカルフォント
@font-face {
font-family: "Open Sans";
font-weight: 400;
font-style: normal;
src: url("OpenSans400.woff2") format("woff2");
}
方法2:クラスを使ったフォント
読み込み中にフォントを表示する2つ目の方法は、クラスを使う方法です。これらのクラスは通常(常にではありませんが)<body> または <html> 要素に追加されます。
この方法の利点は、fallback フォントと Flash of Unstyled Text のタイミングをより細かく制御できることです。
この方法の仕組みは次のとおりです。スタイルシートでページを最初にフォント(fallback フォント)でレンダリングするよう指定します。次に、JavaScript の FontFace API またはプリロードを使ってウェブフォントを読み込みます。フォントが読み込まれたら、ページにクラスを追加します。このクラスによってウェブフォントが有効化されます。
なぜそうするのかと思うかもしれません。fallback フォントをより細かく制御するためです。fallback フォントをより大きな行間隔や異なるサイズで表示し、ウェブフォントとよりマッチさせることができます。これによりレイアウトシフトを防ぐことができます。
複数のウェブフォントを使用する場合、FontFace API メソッドを使ってすべてのフォントを一度に切り替えることができます。これにより、ブラウザの再描画を大幅に削減できます。個人的にはこの方法のファンではありません。FOUT が最後のフォントが読み込まれた後に発生することになり、常に必要以上に遅くなります。
FontFace API を使ったクラス付きフォント:
<style>
//fallback font met een .9rem font-size
html{
font-family: sans-serif;
font-size:.9rem;
}
//webfont font met een 1rem font-size
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'
});
// don't wait for the render tree, initiate an immediate fetch!
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>
//fallback font met een .9rem font-size
html{
font-family: sans-serif;
font-size:.9rem;
}
//webfont font met een 1rem font-size
html.fl{
font-family: 'webfont';
font-size:1rem;
}
//fontface, wordt pas geactiveerd zodra de .fl class wordt toegevoegd aan de html tag
@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 経由のウェブフォントよりも常に高速です。
Lab data is not enough.
I analyze your field data to find the edge cases failing your user experience.
- Real User Data
- Edge Case Detection
- UX Focused

