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

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

「Ensure text remains visible during webfont load」の概要

ウェブフォントとは、ウェブブラウザでデフォルトでは使用できないフォントのことです。ウェブフォントは使用前にダウンロードする必要があります。ウェブフォントのダウンロード中、ウェブページ上のテキストはウェブフォントの読み込みが完了するまで一時的に非表示になります。

その結果、訪問者にとってページの「読み込みが完了していない」ように見えるため、ページの読み込みが非常に遅く感じられます。これは user experience の低下につながる可能性があります。Lighthouse でページを分析すると、ページの読み込みパフォーマンスに関する警告が表示されます:「Ensure text remains visible during webfont load」。

これは font-display の値を変更するか、フォントローダーを使用することで解決できます。この記事でその方法を説明します。

Ensure text remains visible during webfont load

ウェブフォントの読み込み中にテキストを表示し続ける方法

ウェブフォントが登場する前、ウェブデザイナーはプリインストールされた少数のフォントしか使えませんでした。ウェブフォントにより、ウェブサイトで好きなフォントを自由に使えるようになりました。 

もちろんそれは素晴らしいことですが、ウェブフォントにはデメリットもあります。いくつかの点でページの読み込み速度を低下させます。

ウェブフォントは通常、コンピュータにデフォルトでインストールされていない大きなファイルです。そのため、ウェブフォントは使用前にダウンロードする必要があります。ウェブフォントのダウンロード中、ウェブページ上のテキストはウェブフォントの読み込みが完全に完了するまで一時的に非表示になります。これは user experience を損ないます。誰も空白の画面を長時間見つめたくはありません。

ウェブフォントが読み込まれてレンダリングされると、ブラウザは「非表示のテキスト」を新しいウェブフォントの最終テキストに置き換えます。この瞬間を Flash of Invisible Text(FOIT)と呼びます。この FOIT が「Ensure text remains visible during webfont load」というエラーメッセージが表示される原因です。

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 TextFOIT met een webfont

display:swap で Flash of Invisible Text なしGeen FOIT met een webfont

ご覧の通り、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 接続を使用でき、追加のスタイルシートをダウンロードする必要もありません。

ローカルフォント

ローカルフォントを使用していますか?(素晴らしいことです!Google fonts よりもはるかに高速です。)その場合、@font-face ルールに独自の font-display: swap を追加できます。

@font-facefont-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 を使ったクラス付きフォント:

クラス付きフォントを使用する最初の方法は、FontFace API を使う方法です。JavaScript でウェブフォントを読み込みます。フォントが読み込まれたらクラスを追加します。
<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>

追加のヒントとコツ

  1.    表示されるフォントは常にプリロードしましょう。フォントはデフォルトでは使用されるまでダウンロードされません。本当にウェブフォントが必要ですか?その場合、プリロードして早く利用可能にしましょう。
  2. FOIT も FOUT も完全に回避したいですか?font-display: optional とプリロードを組み合わせて使用しましょう。
  3. ウェブフォントを自分でホストする方が、Google fonts や他の外部 CDN 経由のウェブフォントよりも常に高速です。

Lab data is not enough.

I analyze your field data to find the edge cases failing your user experience.

Analyze My Data >>

  • Real User Data
  • Edge Case Detection
  • UX Focused
「Ensure text remains visible during webfont load」の修正方法Core Web Vitals 「Ensure text remains visible during webfont load」の修正方法