23
14

More than 3 years have passed since last update.

Webフォントを使うためのベストプラクティス(最もパフォーマンスがよい、遅延が少ない)をGoogle Fontsの利用を中心に考えてみたいと思います。

形式

EOT・TTF・WOFF・WOFF2・SVG等ありますが、2019年12月現在、ほとんどのブラウザでWOFFとWOFF2がサポートされていますので、この2つを読み込めばOKです。
※但し、案件ごとのターゲットブラウザは確認しましょう。
スクリーンショット 2019-09-30 12.57.25.png
スクリーンショット 2019-09-30 12.57.09.png

Google FontsのCDN利用

Google Fontsをタグで読み込んで使う場合、複数フォントを読み込むと以下のようなタグが発行されます。

<link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP:400,700|Roboto:400,700&display=swap&subset=japanese" rel="stylesheet">

W3Cのチェッカーでエラーでますので、文法エラー回避のためには、でなく%7Cを使います。


メリット

楽に使える

デメリット

レンダリングブロックが発生する

ファイルパスが変わる可能性がある

ブラウザによる挙動の違い

スクリーンショット 2019-09-30 14.44.00.png

発生しやすい問題

FOUT(Flash of Unstyled Text)

Webフォントの読み込みが完了するまで代替フォントで表示され、読み込みが完了するとWebフォントに切り替わる現象。
Chromeなどのブラウザはタイムアウトまでにロードが完了しなかった場合、代替フォントが表示され、フォントダウンロード後に指定フォントに切り替わるため、そのときにチラつきが発生する問題。

FOIT(Flash of Invisible Text)

Webフォントの読み込みが完了するまで、テキストが表示されない現象。
Safariではフォントのロードを待ち続けるように実装されているため、フォントのダウンロードが完了するまでテキストが表示されなくなる問題。

CSSによる最適化

前項のように、ブラウザによって挙動の違いがあり、FOUTやFOITのような問題が発生する場合があります。
font-displayプロパティは、フォント読込中の挙動をCSSから制御することができます。


メリット

レンダリンクブロックが発生しない(非同期読み込み)

細かくフォントの挙動を制御できる

Edge、IEでの利用可能


スクリーンショット 2019-09-30 15.19.24.png
  • autoは、ブラウザのデフォルトの挙動です。
  • blockは、タイムアウトがなくなるため、FOUTはなくなるが、FOITが発生しやすくなります。
  • swapは、ブロック期:0秒、スワップ期:無限で、FOITはなくなるが、FOUTが発生しやすくなります。
  • fallbackは、ブロック期:0.1秒、スワップ期:3秒で、フォールバックフォント表示が許容される場合に使用します。
  • opticalは、ブロック期:0.1秒、スワップ期:0秒で、FOUTは発生せず、FOITも最小限です。ただし、フォントを取得するかどうかブラウザ任せになるため、早いテキスト表示を優先する場合に使うとよいです。

JavaScriptによる最適化

Font Loading API

フォントのダウンロード進行状況の監視や挙動の制御ができるが、ブラウザの実装に差があるため、次に紹介するWeb Font Loaderのほうが使いやすいです。

Web Font Loader

GoogleとTypekitが共同開発したフォントの読み込みを制御できるJavaScriptライブラリ。ソースコードはGitHubで公開されており、無料で利用できます。使い方はNoto Sans JPの使用例にて後述します。

preloadによる最適化

スクリーンショット 2019-09-30 16.00.02.png


メリット

Web Font Loaderより読み込み(レンダリング)が早い

AMPでも利用可能

デメリット

IE、Firefox非対応

CDNは使えない

FOUTが発生する可能性はある

Noto Sans JPの使用例

HTML
<script>
  WebFontConfig={
    google:{
      families:['Roboto:400,700', 'Noto+Sans+JP:400,700']
    },
    active: function() {
      sessionStorage.fonts = true;
    }
  };

  if (typeof WebFont === 'object') {
    WebFont.load(WebFontConfig);
  }
</script>

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" async></script>

<link rel="preload" as="font" href="/assets/fonts/yakuhanjp/YakuHanJP-Regular.woff2" crossorigin>
<link rel="preload" as="font" href="/assets/fonts/yakuhanjp/YakuHanJP-Bold.woff2" crossorigin>
<link rel="preload" as="font" href="/assets/fonts/yakuhanjp/YakuHanJP-Regular.woff" crossorigin>
<link rel="preload" as="font" href="/assets/fonts/yakuhanjp/YakuHanJP-Bold.woff" crossorigin>
CSS
@font-face {
  font-family: "YakuHanJP_Noto";
  font-weight: 400;
  font-style: normal;
  src: url("/assets/fonts/yakuhanjp/YakuHanJP-Regular.woff2") format("woff2"), url("/assets/fonts/yakuhanjp/YakuHanJP-Regular.woff") format("woff");
  font-display: swap;
}

@font-face {
  font-family: "YakuHanJP_Noto";
  font-weight: 700;
  font-style: normal;
  src: url("/assets/fonts/yakuhanjp/YakuHanJP-Bold.woff2") format("woff2"), url("/assets/fonts/yakuhanjp/YakuHanJP-Bold.woff") format("woff");
  font-display: swap;
}
}

sessionStorageの使用

ブラウザを閉じるまで、ページ遷移してもWebフォントを再読み込みする無駄が発生しないようにしています。

非同期の読み込みファイルはscriptタグで記述

GithubのREADMEの記述は、スクリプトインジェクション等の可能性があり、脆弱性の観点からあまりよい記述でないといえます。シンプルにscriptタグのasync属性を利用したコードで記述しています。
また、非同期で読み込んだ場合、WebFont.load()が実行されるタイミングでWeb Font Loaderの読込が完了していない可能性があるため、WebFontのtypeofをチェックして未完了の時は実行されないようにしています。

Noto Sans JPで気になる約物はYaku Hans JPを使用

半角の約物だけのWebフォントで、Noto Sansに最適化されたフォントファイルもあります。
https://github.com/qrac/yakuhanjp
例としてYaku Hansにはpreloadを使っていますが、WebFontLoaderでも記述できます

参照元

ウェブフォントの最適化 | Web Fundamentals | Google Developers
「ブラウザによる挙動の違い」の掲載内容は、参照元から転用させていただいています。

23
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
14