Google Fonts を遅延で読み込みサイト表示を高速化

Web Font LoaderでGoogle Fontsを遅延読み込み

Akira

福岡在住ウェブデザイナー。 WordPress のカスタマイズを、「見やすさ」と「使いやすさ」にこだわり紹介しています。

デバイスを問わず、表示させたいフォントをそのまま表示できるのが Google Fonts のメリットです。

また、豊富な種類を無料で利用できるのも嬉しいポイント。

しかし、サイト表示が遅くなるのが、 Google Fonts のデメリットです。遅くなる原因の 1 つに、レンダリングをブロックしてしまうことが挙げられます。

そこで Web Font Loader を使い、読み込みを遅延させる方法をご紹介します。

多くの海外サイトが利用している Web Font Loader を使うことで、レンダリングブロックを抑えて Google Fonts を利用できます。

Web Font Loader の使い方は非常に簡単

Web Font Loader は、Google と Typekit が共同開発したフォントの読み込みを制御できる JavaScript ライブラリです。

ソースコードは GitHub で公開されており、無料で利用できます。

Web Font Loader を使うコードは、 Binar::Apps が紹介している 「FOUT with Web Font Loader」 を参考にします。

この記事では sessionStorage を使い、 Web Font Loader を利用しています。

そのため、サイト訪問者がブラウザを閉じるまで、ページを移動しても Web フォントを再読み込みする無駄が生じません。

正式版の Google Fonts を読み込ませる方法

Google Fonts で公開されているフォントは、フォント名を指定するだけで遅延読み込みが可能です。

Roboto の regular 400 を読み込ませる場合には、以下のコードを用います。 JavaScript を追加するファイルに追加するか、 <script></script> で囲みインラインに記述します。

window.WebFontConfig = {
  google: { families: [ 'Roboto' ] },
  active: function() {
    sessionStorage.fonts = true;
  }
};
(function() {
  var wf = document.createElement('script');
  wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
  wf.type = 'text/javascript';
  wf.async = 'true';
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(wf, s);
})();

google: { families: [ 'Roboto' ] }'Roboto' で使用するフォントを指定します。

2つ以上の Google Fonts を指定することも可能です。

window.WebFontConfig = {
  google: { families: [ 'Roboto:400,500,700','Roboto+Mono','Berkshire+Swash' ] },
  active: function() {
    sessionStorage.fonts = true;
  }
};
以下同じ

カンマ , で区切り、フォント名を追加していくだけと非常に簡単です。

フォント名は、HTML タグで呼び出す際のコードを参考にします。

font-style が regular 、font-weight が 400・500・700 の Roboto を読み込ませる HTML タグは、 <link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700" rel="stylesheet"> です。

https://fonts.googleapis.com/css?family= で指定している Roboto:400,500,700 が使用するフォント名であるため、 HTML タグからコピペができます。

また、 Material icons も、 google: { families: [ 'Material+Icons' ] } で読み込めます。

Google Fonts 日本語を読み込ませる方法

2016年10月から9種類のフォントが公開されているのが、 Google Fonts 日本語

Google Fonts 日本語は早期アクセス版であり、正式版とは URL が異なります。

そのため、 Web Font Loader で読み込む際には、ほんの少し手間が増えます。

Noto Sans Japanese を読み込む場合のコードは以下のとおりです。

window.WebFontConfig = {
  custom: { families: [ 'Noto Sans Japanese' ],
            urls: [ 'https://fonts.googleapis.com/earlyaccess/notosansjapanese.css' ] },
  active: function() {
    sessionStorage.fonts = true;
  }
};
(function() {
  var wf = document.createElement('script');
  wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
  wf.type = 'text/javascript';
  wf.async = 'true';
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(wf, s);
})();

正式版の Google Fonts は、 google: { families: [ ] } でフォント名を指定します。

一方、早期アクセス版の Google Fonts 日本語は、 custom: { families: [ ] } でフォント名を指定します。

フォント名は、 CSS の font-family と同じ Noto Sans Japanese での指定です。 HTML タグ内の notosansjapanese で指定すると、読み込み速度が大幅に低下します。これはその他の Google Fonts 日本語でも同様です。

さらに、 urls: [ "https://fonts.googleapis.com/earlyaccess/notosansjapanese.css" ] と、 URL も指定します。

正式版と日本語を同時に読み込ませる方法

正式版の Google Fonts と Google Fonts 日本語を、同時に読み込ませることもできます。

window.WebFontConfig = {
  google: { families: [ 'Roboto:400,500,700','Roboto+Mono','Berkshire+Swash' ] },
  custom: { families: [ 'Noto Sans Japanese' ],
            urls: [ 'https://fonts.googleapis.com/earlyaccess/notosansjapanese.css' ] },
  active: function() {
    sessionStorage.fonts = true;
  }
};
(function() {
  var wf = document.createElement('script');
  wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js';
  wf.type = 'text/javascript';
  wf.async = 'true';
  var s = document.getElementsByTagName('script')[0];
  s.parentNode.insertBefore(wf, s);
})();

google: { families: [ ] }custom: { families: [ ] } も指定します。

FOUT(ちらつき)を CSS で制御する

Google Fonts に限らず、 Web フォントを非同期または遅延で読み込む際には、 FOUT と呼ばれるちらつきが生じます。

FOUT とは下の動画のように、フォントが途中で変わる現象です。

この FOUT が起きる原因は、 Web フォントの読み込みが完了するまで、スタイルが適用されていないテキストが表示されるためです。(動画の最初には、動画撮影に使った Chromebook のローカルフォント Noto Sans CJK JP で表示されている。)

そして、読み込みが完了すると Web フォントに変わります。(動画では、読み込んださわらび明朝に変わっている。)

このため、フォントがちらつき、見にくい印象を与えます。

さらに日本語の Web フォントは、フォントの切り替わりに少しタイムラグが生じる問題も抱えています。(動画では、フォント切り替わり時に一瞬テキストが消えている。)

Web Font Loader では、この FOUT の対策も可能です。

Web Font Loader は、フォントイベントに対応したクラス名を <html> 要素に付与します。

CSS で主に利用する付与されるクラス名は以下のとおりです。

  • .wf-loading:フォントを読み込み中の時
  • .wf-active:フォントの読み込みが完了した時
  • .wf-inactive:フォントの読み込みに失敗、またはブラウザが Web フォントに対応していない時

他にフォント毎に付与される3つのクラス名もありますが、 CSS ではあまり使わないため省略しています。詳しくは GitHub 内の Events をご覧ください。

この <html> 要素に付与されるクラス名を使い、 CSS を指定します。

#site-title a {
  font-family: 'Sawarabi Mincho';
  visibility: hidden;
}

.wf-active #site-title a {
  visibility: visible;
}

上記の CSS はサイトタイトルに Sawarabi Mincho を指定し、まずは非表示にしています。ただし、display: none; での非表示ではないため、レイアウトは崩れません。

フォントの読み込みが完了し .wf-active のクラス名が <html> に付与されると、 visibility: visible; でサイトタイトルを表示しています。

この CSS を指定すると、下の動画のように表示されます。

Web フォントの読み込みが完了するまでテキストは表示されないため、フォントが切り替わることがなくなります。

この CSS での FOUT の制御は、 Adobe のフォントイベントが推奨している方法です。

<body> タグに Google Fonts を指定する場合には、ファーストビューで確認できるテキストに CSS で FOUT 対策を行うといいでしょう。

もっと細かく FOUT を制御

Adobe は、より細かく CSS を指定することも推奨しています。

例えば、こんな感じ。

#site-title a {
  font-family: Georgia, serif;
  font-size: 25px;
  letter-spacing: 1px;
  position: relative;
  top: 2px;
}

.wf-active #site-title a {
  font-family: Vollkorn, serif;
  font-size: 24px;
  letter-spacing: 0;
}

.wf-active #site-title a に、最終的に表示する Google Fonts の Vollkorn を指定しています。

それに加え #site-title a に、 Vollkorn が読み込まれるまで Georgia を表示するよう指定しています。さらにフォントサイズや字間、位置も調整。

この指定をすると、下記の動画のように FOUT を抑えることが可能です。

FOUT は発生しています。しかし、お互い似た書体であるため、ちらつきをだいぶ抑えられています。 letter-spacing をもっと突き詰めれば、さらにちらつきは抑えられるはず。

似たフォントを探す手間がかかりますが、テキストは瞬時に表示したいとお考えの方に適しています。

サイトの美しさとサイト表示速度が両立

Google Fonts は、サイトを華やかにしてくれます。また、テキストが読みやすいサイトになるのも大きな魅力です。

しかし、サイト表示速度を犠牲にしていては、サイト訪問者を失望させます。

美しさも速さも両立させるために、 Web Font Loader を利用してはいかがでしょうか。

特に FOUT を制御できるのは、 Web Font Loader ならではの魅力です。

ちなみに、 @import で Web フォントを読み込むのは、絶対におすすめできません。ものすごくサイト表示が遅くなります。