Google Fontsの読み込みを高速化する方法

cover

みなさんはGoogle Fontは好きですか?私は大好きです。タグを書くだけでフォントを利用できるなんてサイト作りにおいて最高ですよね。が、もしかすると、あなたのサイトにおいてフォントがサイトの速度を落とす原因になっているかもしれません。そんな人に向けての記事になります。

TL;DL

  • 日本語フォントの利用は気軽さとパフォーマンスとのトレードオフ
  • できればフォントをセルフホストしよう
  • preconnectdisplay: swap を使うこと

Google Fontsについて

日本語フォントのファイルサイズが大きい

Google Fontsの利用は、最もシンプルなパターンであれば、<head>タグに、指定されたタグを埋め込む作業のみで完結します。ゆえに簡単に導入しがちですが、公式サイトに記載の方法でそのまま利用すると、Webサイトの速度を遅くする原因になる可能性があります。

特にフォントの表現する文字範囲が膨大な日本語を含むフォントである場合は注意です。最も利用されているであろう(推測)フォントのNoto Sans JapaneseのファイルサイズをDev Toolを用いて確認してみましょう。すると、117KBという結果になりました。

noto sans 117KB

しかも、このファイルにフォントが含まれているわけではありません。このファイルは、取得するフォントファイルの目次みたいなもので、このファイルから実際のフォントのデータが分割されて保存されています。すると結果は579kbにもなります。

noto sans 4_2mb

参考に本ページのHTMLのが約20KBなので比較すると相当大きいファイルを取り込まねばなりません。特にファイルサイズが大きくなる原因は、フォントに含まれる文字の数で、なかでも漢字の文字範囲の数が多いためです。

一方で比較対象として英語圏向けのフォントを紹介します。当時Figmaのデザイナーが開発して一躍有名になったInterというフォントがあります。InterもGoogle Fontsから利用できるため、同様にフォントサイズを確認してみましょう。すると、24.1KBになります。明らかにサイズの差があります。

inter 24KB

Noto Sans JPを利用したときのダウンロードするファイル数の多さも気になりますね。しかし膨大な「字」のフォントを利用するためには必要なのです。しかし、現実的には日本語を主とする以上は、Webサイトから漢字を減らすわけにはいかないため、文字フォントをダウンロードしなければなりません。そこでいくつか取りうることのできる工夫を紹介します。

高速化の方法について

Googleのサーバから取得せず、自身のサーバから読み込む

Google Fontsからフォントファイルをダウンロードして、そのファイルを自身のサーバのローカルに配置(セルフホストともいう)する方法です。この方法を利用すれば、Google へのネットワーク通信を減らすことが可能です。フォントファイルは滅多に変更されることがないため、一度キャッシュさせておけば長時間高速でレスポンスを返すことができます。

一方で、ただしこの方法は、配置したフォントファイルをサーバ、もしくはクライアントに適切にキャッシュさせておく必要がなります。キャッシュさせない場合は、むしろGoogle Fonts からの取得の方が早い可能性が高まる可能性もあります。

まずは、ここでは一般的な方法を紹介しておきたいと思います。使いたいフォントをダウンロードします。選んだフォントの右のペインからDonwload allを選択すると、選んだフォントをローカルにダウンロードが可能です。

self-download.png.png

ダウンロードしたら ttfファイル(TrueType)が格納されています。このフォーマットはWebサイト向けではないため、woffもしくはwoff2に別の変換しておくとよいでしょう。これらのフォーマットはWebサイトの用途向けに最適化されていいます。例えば、 woff に変換しておきましょう。変換するサイトは何でもいいですが、今回は TTF to WOFF というサイトを利用させてもらいました。ttf形式では5596KBだったフォントファイルが、woff形式では3333KBになりました。

最後にダウンロードしたttfwoffの二種類のファイルをサーバ上の任意の位置に配置します。 /fonts/ のディレクトリの配下に配置したとしましょう。そしてCSSから @font-face を利用して読み込みます。下記のように指定することでwoffが利用できる環境ではwoffを、そうでない環境ではttfを利用することが可能になります。

@font-face {
  font-family: "Noto Sans JP";
  src:
    url("/fonts/Noto+Sans+JP.woff") format("woff"),
    url("/fonts/Noto+Sans+JP.ttf") format("ttf"),
  display: swap;
}

ちなみに二種類配置する理由としては、 基本は上に書いたフォーマットを先しますが、woff が利用できない環境の場合は ttfを利用する(フォールバックとも言います)ためです。最新のパソコンやモバイル端末であれば、ほぼ間違いなくwoffが選ばれます。

こうすることでCSSのfont-familyから利用できるようになります。これでブラウザは外部サーバを利用せずに自身のサーバからフォントを取得できます。

body {
  font-family: "Noto Sans JP", sans-serif;
}

これで無事に高速になることを確認できた…かというと、実はそこまで単純な話ではありません。

大前提としてGoogle Fonts からのフォントのダウンロード処理は、超高速で最適化されています。前述の画像でも示されていた通り、巨大なファイルを分割して、チャンク化してブラウザは並行してダウンロードする仕組みになっています。

それでも外部リンクとのインターネット通信の負荷を考えると、サーバに置いておくほうが好ましい場合が多いです。Google Fontsと比較してのデメリットとしては、フォントを管理する面倒になり気軽さを享受できないこと、そしてフォントが更新されないことでしょうか。

文字をサブセット化して取得する

利用には制限がありますが、場合によってはオススメできる方法です。サブセット化させるとは、Webサイトに必要な文字のみを抽出し、そのひらがなや漢字などのみフォントファイルを取得する方法です。

Google FontsのURLのパラメータに利用する文字だけを指定することで、指定した文字だけを切り出してフォントを取得(サブセット化)させることができます。

前述したURLにtext={利用したい文字列}を追加するだけです。例えば、先ほど利用したNoto Sans JPで「こんにちは」に絞ってみましょう。<link>タグの指定は次のようになります。

<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap&text=こんにちは"
  rel="stylesheet"
/>

そしてWebサイトで利用してみましょう。すると、

2_6b.png

ファイルサイズが 2.6kBまで減らすことができました。やりましたね✌

が、当然ながら、この状態であれば「こ」「ん」「に」「ち」「は」の5文字のみがNoto Sans JPが採用されることになります。これでは使えません。サブセット化するデメリットはサブセットであることです。すなわちサイト全体で使いたい!であれば、事前にどの文字を使うかを決めることができません。なので基本的にはフルでダウンロードするしかありません。

しかし、例えばですが、

  • 日付表示にのみ特定のフォントを適用させたい
  • ヘッダやフッタのロゴにのみ特定のフォントを適用させたい

このような場合には、フルでフォントをダウンロードする必要がないため、非常に有効な方法になります。

地味に効く小技の紹介

ここではほんの少しだけ高速化する小技を紹介します。いずれもGoogle FontsをWebからダウンロードしている場合の技です。

preconnect で事前にサーバと接続

ブラウザの仕組みを利用してリソースの先読みをすることができます。以下のタグの上二つの <link rel="preconnect...” というタグが先読みをさせるための命令です。このタグを<head>タグのなるべく早めの位置で登場させておきます。

詳しい方向けの説明としては、ブラウザがこのタグを読み込んだ時点で、DNSの名前解決とTCPコネクションの確立を事前に実施してくれるというものです。微々たる効果かもしれませんが、フォントは必ず使うものなので付与しておいて損はないでしょう。

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

display=swap でダウンロード中には別フォントを表示

Googleフォントのダウンロード時に初期から付与されていますが、URLパラメータにdisplay=swapをつけることで表示速度が改善されます。これはフォントを取得するまでは、端末のデフォルトフォントを表示しておいて、取得が完了したら指定したフォントに切り替えるというものです。

このパラメータを付与しなければ、フォントのダウンロードまで初期表示が遅れるため、ローディングに時間がかかる印象を与えることになります。反対に途中でフォントがガクッと変わるため違和感を感じる可能性がありますが、小技としてどうぞ。

複数フォントの同時ロード

複数のフォントを読み込みたい場合、フォントの読み込みのための<link>タグを一つにまとめてしまいましょう。

例えば、二種類のフォントをまとめたい場合ですが、このように冗長にして書かずに…

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Rampart+One&display=swap"
  rel="stylesheet"
/>

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Inter+Tight&display=swap"
  rel="stylesheet"
/>

以下のようにfamilyパラメータにまとめて記載することができます。これをするだけで通信回数が減らすことができます。preconnect も一度だけ記載すれば十分です。

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght&family=Rampart+One&display=swap"
  rel="stylesheet"
/>

さいごに

Google Fonts は利用する気軽さと反面に日本語を利用する民にとっては、ファイルが巨大すぎるという問題を同時にはらんでいます。ページのパフォーマンスを低下させる大きな要因になるので注意しましょう。

ちなみにフォントを利用せずに画像にしてしまうという手段もあります。ヘッダーやフッターなど変化しにくい場所はこの方法でもよいでしょう。どちらの方が良いかはフォントサイズと画像サイズの比較になるので一概には言えませんが、そういう手段もあるのだなと理解して捉えてくれればいいと思います。