オプションのフォントをプリロードして、レイアウト シフトと非表示テキスト(FOIT)の点滅を防ぐ

Chrome 83 以降、link rel="preload" と font-display: optional を組み合わせてレイアウト ジャンクを完全に削除できます

Chrome 83 ではレンダリング サイクルが最適化され、オプションのフォントをプリロードする際のレイアウト シフトがなくなります。 カスタム フォントのレンダリング時にレイアウト ジャンクが発生しないようにするには、<link rel="preload">font-display: optional を組み合わせるのが最も効果的です。

クロスブラウザの最新サポート情報については、MDN のデータをご覧ください。

フォントのレンダリング

レイアウト シフト(再レイアウト)は、ウェブページ上のリソースが動的に変更され、コンテンツが「シフト」したときに発生します。ウェブフォントを取得してレンダリングすると、次の 2 つの方法のいずれかでレイアウト シフトが直接発生する可能性があります。

  • 代替フォントが新しいフォントにスワップされる(「スタイル設定されていないテキストのフラッシュ」)
  • 新しいフォントがページにレンダリングされるまで「非表示」テキストが表示されます(「非表示テキストのフラッシュ」)

CSS の font-display プロパティを使用すると、サポートされているさまざまな値(autoblockswapfallbackoptional)を使用して、カスタム フォントのレンダリング動作を変更できます。使用する値は、非同期で読み込まれるフォントの望ましい動作によって異なります。ただし、これまでは、上記の 2 つの方法のいずれかで、サポートされている値のどれでも再レイアウトがトリガーされる可能性があります。

オプションのフォント

font-display プロパティは、レンダリングする前にダウンロードする必要があるフォントを処理するために、3 つのピリオドのタイムラインを使用します。

  • ブロック: 「非表示」のテキストをレンダリングしますが、読み込みが完了したらすぐにウェブフォントに切り替えます。
  • Swap: 代替システム フォントを使用してテキストをレンダリングしますが、読み込みが完了したらすぐにウェブフォントに切り替えます。
  • 問題がある場合: 代替システム フォントを使用してテキストをレンダリングする。

これまで、font-display: optional で指定されたフォントのブロック期間は 100 ミリ秒で、スワップ期間はありませんでした。つまり、「非表示」のテキストは代替フォントに切り替える前にごく短時間表示されます。フォントが 100 ミリ秒以内にダウンロードされなかった場合、代替フォントが使用され、スワップは行われません。

フォントの読み込みに失敗した場合の以前のフォント動作(省略可)を示す図
100 ミリ秒のブロック期間が経過した後にフォントがダウンロードされた場合の Chrome の以前の font-display: optional の動作

ただし、100 ミリ秒のブロック期間が完了する前にフォントがダウンロードされた場合は、カスタム フォントがレンダリングされ、ページで使用されます。

フォントが時間内に読み込まれた場合の以前の任意のフォント動作を示す図
フォントが 100 ミリ秒のブロック期間より前にダウンロードされた場合の Chrome の以前の font-display: optional の動作

Chrome は、代替フォントが使用されているかどうかや、カスタム フォントの読み込みが時間内に終了したかどうかに関係なく、どちらの場合もページを 2 回再レンダリングします。これにより、目に見えないテキストがわずかにちらつきます。また、新しいフォントがレンダリングされると、レイアウト ジャンクが発生し、ページのコンテンツの一部が移動します。これは、フォントがブラウザのディスク キャッシュに保存されていて、ブロック期間が完了するかなり前に読み込むことができる場合でも発生します。

Chrome 83 では最適化が行われ、<link rel="preload'> でプリロードされているオプション フォントの最初のレンダリング サイクルが完全に削除されています。カスタム フォントの読み込みが完了するか、一定の時間が経過するまで、レンダリングはブロックされます。このタイムアウト時間は、現在 100 ミリ秒に設定されていますが、パフォーマンスを最適化するために、近いうちに変更される可能性があります。

フォントの読み込みに失敗した場合の新しいプリロードされたオプションのフォントの動作を示す図
フォントがプリロードされ、100 ミリ秒のブロック期間が経過した後にフォントがダウンロードされた場合の Chrome の新しい font-display: optional の動作(非表示テキストの点滅なし)
フォントが時間内に読み込まれた場合の、新しいプリロードされたオプションのフォント動作を示す図
フォントがプリロードされ、フォントが 100 ミリ秒のブロック期間より前にダウンロードされた場合の、Chrome の新しい font-display: optional の動作(非表示テキストの点滅なし)

Chrome でオプションのフォントをプリロードすると、レイアウト ジャンクやスタイル設定されていないテキストのフラッシュが発生する可能性がなくなります。これは、CSS Fonts Module Level 4 で指定されている必要な動作と一致します。オプションのフォントによって再レイアウトが発生することはなく、ユーザー エージェントはレンダリングを適切な時間だけ遅らせることができます。

オプションのフォントをプリロードする必要はありませんが、最初のレンダリング サイクルの前にフォントが読み込まれる可能性が大幅に向上します(特に、まだブラウザのキャッシュに保存されていない場合)。

おわりに

Chrome チームでは、これらの新しい最適化によってオプション フォントをプリロードする際のエクスペリエンスについてご意見を伺いたいと考えております。問題が発生した場合や、機能の提案を削除する必要がある場合は、問題を報告してください。