amp-font でフォントの読み込みを監視し FOUT や FOIT を制御

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を紹介しています。AMP が大好き。

FacebookTwitter で記事の更新をお知らせしています。

Google Fonts などの Web フォントを使うと、FOUT や FOIT が発生します。

FOUT
Web フォントの読み込みが完了するまで代替フォントで表示され、読み込みが完了すると Web フォントに切り替わる現象。
FOIT
Web フォントの読み込みが完了するまで、テキストが表示されない現象。

この FOUT や FOIT を制御できるように、AMP では amp-font コンポーネントが提供されています。

この amp-font の使い方をご紹介します。

尚、AMP で Google Fonts を読み込む方法は、下記のページをご参考ください。

amp-font とは?

amp-font は、Web フォントを含むカスタムフォントの読み込みを監視し、読み込みの状況に応じて class の追加や削除を行う AMP コンポーネントです。

<amp-font> タグに指定する属性により、<html> タグの class を操作できます。

例えば、このように指定すると、フォント(Google フォントの Sawarabi Mincho)の表示が可能な時に <html> タグの class に font-success を追加できます。

<amp-font
    layout="nodisplay"
    font-family="Sawarabi Mincho"
    on-load-add-class="font-success">
</amp-font>

<amp-font> タグに指定する属性と操作する class の組み合わせは、下記のとおりです。

amp-font の属性と操作する class の一覧
属性 操作する class の説明
on-load-add-class フォントの表示が可能な時に <html> タグに任意の class を追加する
on-load-remove-class フォントの表示が可能な時に <html> タグから任意の class を削除する
on-error-add-class フォントの使用が可能になる前に timeout 属性で指定した時間が経過すると <html> タグに任意の class を追加する
on-error-remove-class フォントの使用が可能になる前に timeout 属性で指定した時間が経過すると <html> タグから任意の class を削除する

amp-font には、フォントの読み込み状況を判定するまでの待機時間を指定する timeout 属性もあります。

timeout 属性
フォントの読み込みの判定タイミングの最大待機時間を指定する属性。指定がない場合は、デフォルトの 3000(3 秒)が適用される。

例えば、このように指定すると、フォントの読み込み状況の判定を最大 5 秒まで待機します。そして、5 秒以内にフォントの使用が可能にならない場合に、<html> タグの class に font-error を追加できます。

<amp-font
    layout="nodisplay"
    font-family="Sawarabi Mincho"
    timeout="5000"
    on-error-add-class="font-error">
</amp-font>

あとは、追加・削除する class を使い、CSS でフォントをどのように表示するかを指定します。

尚、<amp-font> タグの設置場所は、<body> タグ内であればどこでも構いません(<body> タグの子要素でも孫要素でも可)。

使用例

amp-font を使うには、ライブラリの読み込みが必要です。

下記の <script> タグを <head></head> タグ内に追加します。

<script async custom-element="amp-font" src="https://cdn.ampproject.org/v0/amp-font-0.1.js"></script>

amp-font によるカスタムフォントの FOUT や FOIT の制御方法を 3 つご紹介します。

キャッシュされたフォントのみを使う

FOUT も FOIT も発生させない方法の 1 つが、キャッシュされたカスタムフォントのみを使用するものです。テキストが素早く表示されるのが魅力です。

キャッシュされたカスタムフォントのみを使用する場合は、下記のような <amp-font> タグを <body> タグ内に追加します。Google Fonts の Sawarabi Mincho を読み込んでいるケースとお考えください。

<amp-font
    layout="nodisplay"
    font-family="Sawarabi Mincho"
    timeout="0"
    on-error-add-class="font-error">
</amp-font>

まず、font-family で読み込みを監視するフォントを指定します。CSS の font-family と同じ書き方での指定です。

次に、timeout="0" を指定します。0 の指定で、フォントのキャッシュがブラウザにある場合にのみフォントの利用が可能になります。

最後に、on-error-add-class="font-error" を指定します。フォントのキャッシュがブラウザにない時は、<html> タグの class に font-error が追加されます。

そして、CSS を指定します。

/* CSS の一例 */

/* フォントがキャッシュされている時 */
body {
  font-family: 'Sawarabi Mincho', sans-serif;
}

/* フォントがキャッシュされていない時 */
.font-error body {
  font-family: 'Yu Gothic', '游ゴシック', YuGothic, '游ゴシック体', sans-serif;
}

読み込む Sawarabi Mincho のキャッシュがブラウザにあれば、Sawarabi Mincho で表示します。

キャッシュがなければ、<html> タグの class に追加する font-error を使いローカルフォントで表示するように指定します。読み込む Sawarabi Mincho と書体が似ているフォントの指定が理想です。

この amp-font の使い方は、CSS の font-display: optional; を指定する時とほぼ同じ動作をします(ただし、フォントのダウンロードを開始するかどうかをブラウザに任せるわけではない)。そして、Google は、可能であればとの条件付きで font-display: optional; の使用を推奨しています。

この方法のメリットとデメリットは、下記のとおりです。

キャッシュされたフォントのみを使うメリットとデメリット
メリット
FOUT も FOIT も発生しない
いかなる状況でもテキストがすぐに表示される
デメリット
カスタムフォントのキャッシュがブラウザになければ、カスタムフォントで表示されない

代替フォントによる FOUT の制御

FOIT は発生させたくない、けれど Google Fonts は常に表示したい場合は、代替フォントで FOUT を抑えるようにします。

下記のような <amp-font> タグを <body> タグ内に追加します。Google Fonts の Sorts Mill Goudy を読み込んでいるケースとお考えください。

<amp-font
    layout="nodisplay"
    font-family="Sorts Mill Goudy"
    on-load-add-class="font-success">
</amp-font>

Sorts Mill Goudy が 3 秒以内に読み込まれると、<html> タグの class に font-success が追加されます。

そして、CSS を指定します。

/* CSS の一例 */

/* Sorts Mill Goudy と書体が似ている Garamond を指定 */
h1 {
  font-family: Garamond, serif;
  letter-spacing: 2px;
}

/* Sorts Mill Goudy の表示が可能であればフォントを変更 */
.font-success h1 {
  font-family: 'Sorts Mill Goudy', serif;
  letter-spacing: normal;
}

Sorts Mill Goudy が読み込まれるまでは、書体が似ている Garamond で表示します。また、letter-spacing を調整し、Sorts Mill Goudy になるべく似せます。

Sorts Mill Goudy が読み込まれると、フォントを変更します。

これにより FOUT による文字のちらつきを極力抑えられる上に、FOIT は発生しません。

この指定をしたのが、下の GIF です。スーパーリロード(ブラウザのキャッシュを消し再読み込み)を繰り返しています。

font-size も調整すれば、より FOUT を抑えられます。

この方法のメリットとデメリットは、下記のとおりです。

代替フォントによる FOUT の制御のメリットとデメリット
メリット
FOUT を抑えられる
FOIT は発生しない
カスタムフォントの読み込みによほど時間がかからない限り、常にカスタムフォントを表示できる
デメリット
FOUT を完全に発生させないのは難しい
書体が似ていてローカルにあるであろう代替フォントを探す必要がある
書体が似ている代替フォントがなければ、FOUT の制御は困難

FOIT による FOUT の制御

FOUT は発生させたくない、けれど Google Fonts は常に表示したい場合は、FOIT を発生させ FOUT を制御します。

下記のような <amp-font> タグを <body> タグ内に追加します。Open Sans を読み込んでいるケースとお考えください。

<amp-font
    layout="nodisplay"
    font-family="Open Sans"
    on-load-add-class="font-success"
    on-error-add-class="font-error">
</amp-font>

この例では、Open Sans が 3 秒以内に読み込まれた場合に <html> タグの class に font-success が追加されます。

また、何かしらの理由で Open Sans の読み込みに失敗した時に備えて、on-error-add-class="font-error" も指定します。

そして、CSS を指定します。

/* CSS の一例 */

/* amp-font が判定している間は非表示にする */
h1 {
  visibility: hidden;
}

/* Open Sans の表示が可能な場合は Open Sans で表示 */
.font-success h1 {
  font-family: 'Open Sans', sans-serif;
  visibility: visible;
}

/* Open Sans の表示が不可能な場合はローカルフォントで表示 */
.font-error h1 {
  font-family: Arial, sans-serif;
  visibility: visible;
}

amp-font が Open Sans の読み込みを判定するまでは、テキストを非表示にしておきます。

そして、3 秒以内に Open Sans が読み込まれると、Open Sans でテキストを表示します。

3 秒を超えても Open Sans が読み込まれない場合は、ローカルフォントで表示します。

これにより FOUT が発生せず、よほど読み込みに時間がかからない限り Open Sans を常に表示できます。

この方法のメリットとデメリットは、下記のとおりです。

FOIT による FOUT の制御のメリットとデメリット
メリット
FOUT が発生しない
カスタムフォントの読み込みによほど時間がかからない限り、常にカスタムフォントを表示できる
デメリット
テキストがすぐに表示されない FOIT が発生する(FOIT の発生は好まれていない)

送信に失敗しました

ボットと判定された可能性があります。

大変お手数をおかけしますが、以下の内容をご確認の上、再度のコメントの送信をお願い申し上げます。