フォントに関するおすすめの方法

Core Web Vitals 向けにウェブフォントを最適化します。

このドキュメントでは、フォントのパフォーマンスに関するベスト プラクティスについて説明します。ウェブフォントがパフォーマンスに影響を与える方法はさまざまです。

  • テキストのレンダリングの遅延: ウェブフォントが読み込まれていない場合、ブラウザは通常、テキストのレンダリングを遅延させます。多くの場合、これにより First Contentful Paint(FCP)が遅延します。状況によっては、これにより Largest Contentful Paint(LCP)が遅延します。
  • レイアウトの移動: フォントの入れ替えは、レイアウトの移動を引き起こしCumulative Layout Shift(CLS)に影響を与える可能性があります。レイアウト シフトは、ウェブフォントとそのフォールバック フォントがページ上で異なるスペースを占有する場合に発生します。

このドキュメントは、フォントの読み込みフォントの配信フォントのレンダリングの 3 つのセクションで構成されています。各セクションでは、フォント ライフサイクルの特定の側面がどのように機能するかを説明し、対応するベスト プラクティスを示します。

フォントの読み込み

フォントは重要なリソースです。これらがないと、ユーザーはページ コンテンツを表示できない可能性があります。そのため、フォント読み込みのベスト プラクティスは、一般的にフォントをできるだけ早く読み込むことに重点を置いています。特に、サードパーティのサイトから読み込まれるフォントは、これらのフォント ファイルをダウンロードするために個別の接続設定が必要になるため、注意が必要です。

ページのフォントが時間内にリクエストされているかどうか不明な場合は、Chrome DevTools の [Network] パネルの [Timing] タブで詳細を確認してください。

DevTools の [タイミング] タブ。

@font-face について理解する

フォント読み込みのベスト プラクティスについて詳しく説明する前に、@font-face の仕組みと、それがフォント読み込みにどのように影響するかを理解しておくことが重要です。

@font-face 宣言は、ウェブフォントを使用するうえで不可欠な要素です。少なくとも、フォントを参照するために使用される名前を宣言し、対応するフォント ファイルの場所を示します。

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

よくある誤解として、@font-face 宣言が検出されたときにフォントがリクエストされるというものがあります。これは誤りです。@font-face 宣言だけではフォントのダウンロードはトリガーされません。フォントは、ページで使用されるスタイル設定で参照されている場合にのみダウンロードされます。次に例を示します。

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

h1 {
  font-family: "Open Sans"
}

この例では、ページに <h1> 要素が含まれている場合にのみ Open Sans がダウンロードされます。

したがって、フォントの最適化を考える際は、フォント ファイル自体と同じくらいスタイルシートを考慮することが重要です。スタイルシートの内容や配信を変更すると、フォントの到着時間に大きな影響を与える可能性があります。同様に、使用されていない CSS を削除し、スタイルシートを分割すると、ページで読み込まれるフォントの数を減らすことができます。

インライン フォント宣言

ほとんどのサイトでは、フォント宣言やその他の重要なスタイル設定を外部スタイルシートに含めるのではなく、メイン ドキュメントの <head> にインライン化することで、大きなメリットが得られます。これにより、ブラウザは外部スタイルシートのダウンロードを待つ必要がないため、フォント宣言をより早く検出できます。

<head>
  <style>
    @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    }

    body {
        font-family: "Open Sans";
    }

    ...etc.

  </style>
</head>

重要な CSS をインライン化することは、すべてのサイトで実現できる高度な手法ではありません。パフォーマンス上のメリットは明らかですが、必要な CSS(できれば重要な CSS のみ)が正しくインライン化され、追加の CSS がレンダリングをブロックしない方法で配信されるように、追加のプロセスとビルドツールが必要になります。

重要なサードパーティのオリジンに事前接続する

サイトでサードパーティ サイトからフォントを読み込む場合は、preconnect リソースヒントを使用して、サードパーティのオリジンとの早期接続を確立することを強くおすすめします。リソース ヒントは、ドキュメントの <head> に配置する必要があります。次のリソースヒントは、フォント スタイルシートを読み込むための接続を設定します。

<head>
  <link rel="preconnect" href="https://fonts.com">
</head>

フォント ファイルのダウンロードに使用される接続をプリコネクトするには、crossorigin 属性を使用する別の preconnect リソースヒントを追加します。スタイルシートとは異なり、フォントファイルは CORS 接続を介して送信する必要があります。

<head>
  <link rel="preconnect" href="https://fonts.com">
  <link rel="preconnect" href="https://fonts.com" crossorigin>
</head>

preconnect リソースヒントを使用する際は、フォント プロバイダが別々のオリジンからスタイルシートとフォントを配信する可能性があることに注意してください。たとえば、Google Fonts で preconnect リソースヒントを使用する方法は次のとおりです。

<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

preload を使用してフォントを読み込む場合は注意が必要です

preload は、ページ読み込みプロセスの早い段階でフォントを検出できるようにするうえで非常に効果的ですが、他のリソースの読み込みからブラウザのリソースを奪うという代償が伴います。

フォント宣言をインライン化し、スタイルシートを調整する方が効果的なアプローチになる可能性があります。これらの調整は、単なる回避策ではなく、遅れて検出されたフォントの根本原因に対処するものです。

また、preload をフォント読み込み戦略として使用すると、ブラウザの組み込みコンテンツ ネゴシエーション戦略の一部がバイパスされるため、注意が必要です。たとえば、preloadunicode-range 宣言を無視します。慎重に使用する場合は、単一のフォント形式を読み込む場合にのみ使用する必要があります。

ただし、外部スタイルシートを使用している場合は、最も重要なフォントをプリロードすると非常に効果的です。ブラウザは、それまでフォントが必要かどうかをずっと後まで認識できないためです。

フォントの配信

フォントの配信が速くなると、テキストのレンダリングも速くなります。また、フォントを早めに配信することで、フォントの切り替えによるレイアウト シフトを解消できます。

セルフホスト フォントを使用する

理論上は、サードパーティの接続設定が不要になるため、セルフホスト フォントを使用する方がパフォーマンスが向上します。実際には、この 2 つのオプションのパフォーマンスの違いは明確ではありません。たとえば、Web Almanac によると、サードパーティ製フォントを使用しているサイトは、ファーストパーティ製フォントを使用しているフォントよりもレンダリングが高速でした。

セルフホスト フォントの使用を検討している場合は、サイトでコンテンツ配信ネットワーク(CDN)HTTP/2 が使用されていることを確認してください。これらのテクノロジーを使用しない場合、セルフホスト フォントでパフォーマンスが向上する可能性は大幅に低くなります。

セルフホスト フォントを使用する場合は、サードパーティのフォント プロバイダが通常自動的に提供するフォント ファイルの最適化の一部を適用することをおすすめします。たとえば、フォントのサブセット化や WOFF2 圧縮などです。これらの最適化を適用するために必要な作業量は、サイトでサポートされている言語によって多少異なります。特に、CJK 言語のフォントを最適化するのは非常に難しい場合があります。

WOFF2 を使用する

最新のフォント形式のうち、WOFF2 は最も新しく、ブラウザのサポート範囲が最も広く、圧縮率も最も優れています。Brotli を使用しているため、WOFF2 は WOFF よりも 30% 圧縮率が高く、ダウンロードするデータが少なくなるため、パフォーマンスが向上します。

ブラウザのサポートを考慮すると、専門家は WOFF2 のみを使用することを推奨しています。

実際、WOFF2 のみを使用し、それ以外のことはすべて忘れるべきだと考えています。

これにより、CSS とワークフローが大幅に簡素化され、誤ってフォントを二重にダウンロードしたり、間違ったフォントをダウンロードしたりするのを防ぐこともできます。WOFF2 は、すべてのプラットフォームでサポートされるようになりました。そのため、非常に古いブラウザをサポートする必要がない限り、WOFF2 を使用してください。できない場合は、古いブラウザにはウェブフォントを一切配信しないことを検討してください。堅牢なフォールバック戦略が導入されていれば、問題は発生しません。古いブラウザを使用しているユーザーには、フォールバック フォントが表示されます。

2022 年のウェブ アルマナックより、Bram Stein

フォントをサブセット化する

フォントファイルには通常、サポートするさまざまな文字のグリフが多数含まれています。ただし、ページ上のすべての文字が必要とは限らず、フォントをサブセット化することでフォント ファイルのサイズを縮小できます。

@font-face 宣言の unicode-range ディスクリプタは、フォントで使用できる文字をブラウザに通知します。

@font-face {
    font-family: "Open Sans";
    src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    unicode-range: U+0025-00FF;
}

ページに Unicode 範囲に一致する文字が 1 つ以上含まれている場合、フォントファイルがダウンロードされます。unicode-range は、ページ コンテンツで使用されている言語に応じて異なるフォント ファイルを配信するために一般的に使用されます。

unicode-range は、サブセット化の手法と組み合わせて使用されることがよくあります。サブセット フォントには、元のフォント ファイルに含まれていたグリフの小さな部分が含まれます。たとえば、サイトではすべての文字をすべてのユーザーに配信するのではなく、ラテン文字とキリル文字用に別々のサブセット フォントを生成する場合があります。

フォントあたりのグリフの数は大きく異なります。

  • ラテン文字フォントは、通常、フォントあたり 100 ~ 1,000 個のグリフで構成されています。
  • CJK フォントには 10,000 文字を超える文字が含まれている場合があります。

未使用のグリフを削除すると、フォントのファイルサイズを大幅に削減できます。

一部のフォント プロバイダは、異なるサブセットを含むさまざまなバージョンのフォントファイルを自動的に提供する場合があります。たとえば、Google Fonts はデフォルトでこれを行います。

/* devanagari */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJbecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
}
/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJnecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

セルフホスティングに移行する際に、この最適化を見落とすと、ローカルのフォントファイルが大きくなる可能性があります。

フォント プロバイダが許可している場合は、API(Google Fonts は text パラメータを提供することでこれをサポートしています)を使用するか、フォント ファイルを手動で編集してからセルフホスティングすることで、フォントを手動でサブセット化できます。フォント サブセットを生成するツールには、subfontglyphanger などがあります。

フォント ライセンスを常に確認して、サブセット化とセルフホスティングが許可されていることを確認してください。

ウェブフォントの使用を減らす

最も高速に配信できるフォントは、そもそもリクエストされないフォントです。システム フォントと可変フォントは、サイトで使用されるウェブ フォントの数を減らす可能性がある 2 つの方法です。

システム フォントは、ユーザーのデバイスのユーザー インターフェースで使用されるデフォルトのフォントです。システム フォントは通常、オペレーティング システムとバージョンによって異なります。フォントはすでにインストールされているため、ダウンロードする必要はありません。システム フォントは、特に本文に適しています。

CSS でシステム フォントを使用するには、font-family として system-ui を指定します。

font-family: system-ui

バリアブル フォントのコンセプトは、1 つのバリアブル フォントを複数のフォント ファイルの代わりに使用できるというものです。バリアブル フォントは、「デフォルト」のフォント スタイルを定義し、フォントを操作するための「軸」を提供することで機能します。たとえば、Weight 軸を持つバリアブル フォントを使用すると、以前はライト、レギュラー、ボールド、エクストラ ボールドの個別のフォントが必要だったレタリングを実装できます。

可変フォントに切り替えることで、すべてのユーザーがメリットを得られるわけではありません。可変フォントには多くのスタイルが含まれているため、通常、1 つのスタイルのみを含む個々の非可変フォントよりもファイルサイズが大きくなります。バリアブル フォントを使用することで最も大きな改善が見込めるのは、さまざまなフォント スタイルや太さを使用している(または使用する必要がある)サイトです。

フォントのレンダリング

ウェブフォントがまだ読み込まれていない場合、ブラウザはジレンマに直面します。ウェブフォントが読み込まれるまでテキストのレンダリングを遅らせるべきでしょうか?それとも、ウェブフォントが読み込まれるまでフォールバック フォントでテキストを表示すべきでしょうか?

このシナリオの処理はブラウザによって異なります。デフォルトでは、関連付けられたウェブフォントが読み込まれていない場合、Chromium ベースのブラウザと Firefox ブラウザは最大 3 秒間テキストのレンダリングをブロックします。Safari がテキストのレンダリングを無期限にブロックします。

この動作は、font-display 属性を使用して構成できます。この選択は、LCP、FCP、レイアウトの安定性に影響を与える可能性があるため、大きな影響を与える可能性があります。font-display

適切な font-display 戦略を選択する

font-display は、関連付けられたウェブフォントが読み込まれていない場合に、テキストのレンダリングをどのように進めるべきかをブラウザに伝えます。これはフォントフェイスごとに定義されます。

@font-face {
  font-family: Roboto, Sans-Serif
  src: url(/fonts/roboto.woff) format('woff'),
  font-display: swap;
}

font-display には次の 5 つの値があります。

ブロック期間 スワップ期間
自動 ブラウザによって異なります ブラウザによって異なります
ブロック 2 ~ 3 秒 無限
スワップ 0ms 無限
フォールバック 100ms 3 秒
省略可 100ms なし
  • ブロック期間: ブラウザがウェブフォントをリクエストしたときにブロック期間が開始されます。ブロック期間中、ウェブフォントが利用できない場合、フォントは不可視のフォールバック フォントでレンダリングされるため、ユーザーにはテキストが表示されません。ブロック期間の終了時にフォントが利用できない場合、フォールバック フォントでレンダリングされます。
  • スワップ期間: スワップ期間はブロック期間の後に始まります。スワップ期間中にウェブフォントが利用可能になった場合は、ウェブフォントが「スワップ」されます。

font-display 戦略は、パフォーマンスと美しさのトレードオフに関するさまざまな視点を反映しています。そのため、個人の好み、ウェブフォントがページやブランドにとってどの程度重要か、フォントが遅れて表示された場合にどの程度違和感があるかによって、推奨されるアプローチは異なります。

ほとんどのサイトでは、最優先事項に基づいて、次の 3 つの戦略が最も適しています。

  • パフォーマンス: font-display: optional を使用します。これは最もパフォーマンスの高いアプローチです。テキストのレンダリングが 100 ミリ秒以上遅れることはなく、フォントの切り替えに関連するレイアウト シフトが発生しないことが保証されます。欠点は、ウェブフォントが遅れて到着した場合に使用されないことです。

  • テキストをすばやく表示し、ウェブフォントを使用する: font-display: swap を使用しますが、レイアウトのずれが発生しないように、フォントを十分に早く配信するようにしてください。このオプションの欠点は、フォントの読み込みが遅れた場合に、フォントが突然切り替わることです。

  • テキストがウェブフォントで表示される: font-display: block を使用しますが、テキストの遅延を最小限に抑えるために、フォントを十分に早く配信するようにしてください。最初のテキスト表示が遅延します。この遅延にもかかわらず、テキストは実際には非表示で描画され、フォールバック フォントのスペースがスペースの予約に使用されるため、レイアウト シフトが発生する可能性があります。ウェブフォントが読み込まれると、必要なスペースが異なるため、シフトが発生する可能性があります。テキスト自体は移動しないため、font-display: swap よりも違和感のない移動になる可能性があります。

また、この 2 つのアプローチは組み合わせることもできます。たとえば、ブランディングやその他の視覚的に特徴的なページ要素には font-display: swap を使用します。本文のテキストに使用するフォントには font-display: optional を使用します。

アイコン フォント

従来のウェブフォントで有効な font-display 戦略は、アイコン フォントではあまり有効ではありません。アイコン フォントのフォールバック フォントは、通常、アイコン フォントとは大きく異なり、その文字はまったく異なる意味を表すことがあります。そのため、アイコン フォントはレイアウト シフトを大幅に引き起こす可能性が高くなります。

また、フォールバック フォントの使用は実用的でない場合があります。可能であれば、アイコン フォントを SVG に置き換えます。これはアクセシビリティの面でも優れています。一般的なアイコン フォントの新しいバージョンでは、通常 SVG がサポートされています。SVG への切り替えについて詳しくは、SVG スプライトに関する Font Awesome のページマテリアル アイコン ガイドをご覧ください。

フォールバック フォントとウェブフォント間のずれを減らす

CLS の影響を軽減するには、size-adjust 属性を使用します。

まとめ

ウェブフォントは依然としてパフォーマンスのボトルネックですが、このボトルネックを可能な限り軽減するために最適化できるオプションは増え続けています。