font-display によるフォント パフォーマンスの制御

ウェブフォントが読み込まれるときの動作を決定することは、パフォーマンス チューニングの重要な手法です。@font-face の新しい font-display 記述子を使用すると、デベロッパーは、ウェブフォントの読み込み時間に応じて、ウェブフォントのレンダリング方法(またはフォールバック)を決定できます。

現在のフォント レンダリングの違い

ウェブフォントを使用すると、デベロッパーは豊富なタイポグラフィをプロジェクトに組み込むことができます。ただし、ユーザーがタイポフェイスをまだ所有していない場合、ブラウザはタイポフェイスのダウンロードに時間を要します。ネットワークが不安定な場合、このダウンロード時間はユーザー エクスペリエンスに悪影響を及ぼす可能性があります。表示に時間がかかりすぎるテキストは、どんなに美しくとも誰も気にしません。

フォント ダウンロードの遅延のリスクを軽減するため、ほとんどのブラウザはタイムアウトを実装しています。タイムアウト後に代替フォントが使用されます。これは便利な手法ですが、残念ながら実際の実装はブラウザによって異なります。

ブラウザ タイムアウト フォールバック スワップ
Chrome 35 以降 3 秒 はい はい
Opera 3 秒 はい はい
Firefox 3 秒 はい はい
Internet Explorer 0 秒 はい はい
Safari タイムアウトなし 該当なし 該当なし
  • Chrome と Firefox には 3 秒のタイムアウトがあり、その後テキストは代替フォントで表示されます。フォントがダウンロードに成功した場合、最終的にスワップが発生し、テキストは意図したフォントで再レンダリングされます。
  • Internet Explorer のタイムアウトは 0 秒で、即時にテキストのレンダリングが行われます。リクエストされたフォントがまだ使用できない場合は代替フォントが使用され、リクエストされたフォントが利用可能になるとテキストの再レンダリングを行います。
  • Safari にはタイムアウトの振る舞いはありません(ベースラインのネットワーク タイムアウト以外のものはありません)。

さらに悪いことに、デベロッパーは、これらのルールがアプリケーションに与える影響を制御する手段が限られています。パフォーマンス重視のデベロッパーは、代替フォントを使用して最初のエクスペリエンスを高速化し、ダウンロードが完了した後の再訪時にのみ、より優れたウェブフォントを利用することをおすすめします。Font Loading API などのツールを使用すると、デフォルトのブラウザ動作の一部をオーバーライドしてパフォーマンスを向上させることができますが、その代償として、大量の JavaScript を記述してページにインライン化するか、外部ファイルからリクエストする必要があり、HTTP レイテンシが増加します。

この状況を改善するために、CSS ワーキング グループは、新しい @font-face ディスクリプタ font-display と、ダウンロード可能フォントが完全に読み込まれる前にレンダリングする方法を制御するための対応するプロパティを提案しました。

フォント ダウンロードのタイムライン

一部のブラウザが現在実装している既存のフォント タイムアウト動作と同様に、font-display はフォントのダウンロードの有効期間を 3 つの主要な期間に分割します。

  1. 最初の期間はフォント ブロック期です。この期間中にフォント フェースがロードされていない場合、それを使おうとする要素は、代わりに不可視代替フォント フェースでレンダリングされる必要があります。このブロック期にフォント フェースが正常にロードされた場合、そのフォント フェースは通常どおりに使用されます。
  2. フォント スワップ期は、フォント ブロック期の直後に発生します。この期間中にフォント フェースがロードされていない場合、それを使おうとする要素は、代わりに代替フォント フェースでレンダリングされる必要があります。このスワップ期にフォント フェースが正常にロードされた場合、そのフォント フェースは通常どおりに使用されます。
  3. フォント失敗期は、フォント スワップ期の直後に発生します。この期間の開始時にフォント フェースがまだロードされていない場合、読み込み失敗としてマークされ、通常の代替フォントが使用されます。それ以外の場合は、フォント フェースが通常どおりに使用されます。

これらの期間を理解すると、font-display を使用して、フォントがダウンロードされたかどうか、またはいつダウンロードされるかによってフォントのレンダリング方法を決定できます。

最適な font-display はどれですか?

font-display 記述子を使用するには、@font-face アットルールに追加します。

@font-face {
    font-family: 'Arvo';
    font-display: auto;
    src: local('Arvo'), url(https://fonts.gstatic.com/s/arvo/v9/rC7kKhY-eUDY-ucISTIf5PesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
}

font-display は現在、次の値の範囲 auto | block | swap | fallback | optional をサポートしています。

自動

auto は、user-agent が使用するフォント表示戦略を必ず使用します。ほとんどのブラウザは、現在 block に似たデフォルト戦略を持っています。

ブロック

block を使用すると、フォント フェースのブロック期は短く(ほとんどの場合 3 秒が推奨されます)、スワップ期は無限になります。つまり、フォントが読み込まれていない場合、ブラウザは最初は「不可視」テキストを描画しますが、読み込まれるとすぐにフォント フェースを入れ替えます。これを行うために、ブラウザは、選択されたフォントに似たメトリックで、すべてのグリフに「インク」を含まない匿名のフォント フェースを作成します。この値は、ページを使用可能にするために特定の書体でテキストをレンダリングすることが必要な場合にのみ使用する必要があります。

スワップ

swap を使用すると、フォント フェースのブロック期は 0 秒でスワップ期は無限になります。つまり、フォント フェースが読み込まれていない場合、ブラウザは代替フォントですぐにテキストを描画しますが、読み込まれるとすぐにフォント フェースを入れ替えます。block と同様に、この値は、特定のフォントでテキストをレンダリングすることがページにとって重要ではあるが、どのフォントでレンダリングしてもメッセージは正しく表示される場合にのみ使用する必要があります。ロゴ テキストは swap の候補として適しています。合理的な代替フォントを使用して会社の名前を表示すればメッセージは伝わりますが、最終的には正式な書体を使用することになるためです。

フォールバック

fallback を使用すると、フォント フェースのブロック期は非常に短く(ほとんどの場合 100ms 以下が推奨されます)、スワップ期は短く(ほとんどの場合 3 秒が推奨されます)なります。つまり、フォント フェースが読み込まれていない場合、最初は代替フォントでレンダリングされますが、読み込まれるとすぐにフォントが入れ替わります。ただし、時間がかかりすぎると、残りのページの有効期間は代替フォントが使用されます。代替フォントは、本文のようなものに適しています。ユーザーにできるだけ早く読み始めてもらうと同時に、新しいフォントの読み込み時にテキストを移動させてユーザーの邪魔をしたくないからです。

省略可

省略可: フォント フェースのブロック期は非常に短く(ほとんどの場合 100ms 以下が推奨されます)、スワップ期は 0 秒になります。代替フォントと同様に、これはダウンロードするフォントが「あれば良い」ものの、エクスペリエンスに不可欠な要素ではない場合に適しています。省略可の値は、フォントのダウンロードを開始するかどうかをブラウザに任せます。ユーザーにとって最適と思われることに応じて、フォントのダウンロードをしない場合も、ダウンロードの優先順位を低くする場合もあります。これは、ユーザーの接続が遅いため、フォントの取り込みがリソースの最善の使い方ではないような状況では有益です。

ブラウザ サポート

font-display は現在、パソコン版 Chrome 49 の「試験運用版のウェブ プラットフォームの機能」フラグで利用可能で、Opera と Opera for Android でリリースされています。

デモ

サンプルfont-display を試してみてください。パフォーマンス重視のデベロッパーにとって、これはツールボックスに追加できる便利なツールです。