Next.jsのFont Optimizations(Webフォントの最適化)を試してみる
追記) v10.2からデフォルトでGoogle Fontsの最適化が行われるように
Next.js v10.2から自動でWebフォントの最適化が行われるようになりました。v10.2時点ではGoogle Fontsにのみ対応しているとのことです。特に設定は不要で、いつも通りGoogle Fontsを読み込めばOKです。
↓ 詳細
これより下の解説は古い内容になります。実装の参考にしないようお願いします。
以前、Next.jsのリポジトリを眺めていたときにFont Optimizationsというプルリクエストを見つけました。
2020年12月時点ではExperimantalな機能のようですが、v10.0.4
で既に使えるようになっていたので試してみました。
:::message alertz
Next.js v10.0.4でのドキュメントに則っていない記録になります。
:::
Font Optimizationとは
まだドキュメントに説明が書かれていないので、プルリクエストの説明文を引用します。
...略... we will grab the
<link rel='stylesheet' href='https://fonts.googleapis.com/...'/>
(List of font providers to be extended in future PRs) tags and inline it's content.
出力されたHTMLの中からWebフォントのスタイルシートを見つけて、その中身をインラインで展開してくれるようです。今のところはGoogle Fontsに対応している模様。
This eliminates the extra round trip that the browser has to make to fetch the font declarations. This helps in faster paints and improved LCP.
ものすごくざっくりというと、フォントデータのフェッチ時間を節約できるため表示の高速化が期待できるというわけです。上の文章に書かれている「LCP」はLargest Contentful Paintの略ですね。
どのような仕組みで実現されているか
以下もプルリクエストの引用です。
- Gathering the used <link rel='stylesheet' href='https://fonts.googleapis.com/...'/> tags and downloading their content at build time.
- Replacing the inspected Link tag with a style tag and the content of the href inlined within this style tag at serve/render time.
In order to do the above-said we use.
ビルド時にhttps://fonts.googleapis.com/...
から始まるスタイルシートの読み込みタグを見つけて、その内容をすべてダウンロードするようです。WebフォントをCDNから読み込むより、セルフホストの方がパフォーマンスが良いとされているので、嬉しいですね。
参考
-
Self-hosting fonts vs Google Fonts
... セルフホスティングのフォントとGoogle Fontsの読み込みを比較している記事 -
Gaining security and privacy by partitioning the cache
... Google Chrome 86〜、プライバシーのためCDNのキャッシュが他ドメインのサイトと共有されることがなくなった
と思いきや、実際に試してみて分かったのですが、フォントのデータ(◯◯.woff
)自体はFont Optimizationを使ってもGoogleのサーバーから読み込むようです。今後woff
もダウンロードしたりするのかな?
Font Optimizationのより詳しい仕組みはプルリクを読んでいただくのが良いと思います。
実際に試してみる
HeadでGoogle Fontsを読み込む
では実際に試してみたいと思います。コードを見る限りnext/head
タグ内に配置された<link>
が対象になるようです。というわけで_app.tsx
でGoogle Fontsを読み込みます。
import Head from "next/head"
...略
return (
<Head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@700&display=swap" />
</Head>
)
next.config.jsでFont Optimizationを有効化
v10.0.4時点ではexperimental
内で指定する必要があります。
module.exports = {
experimental: {
optimizeFonts: true,
},
};
たったこれだけで準備完了です。
デプロイして確認
デプロイしてみると、ちゃんとGoogle Fontsが適用されているようです。ソースを見るとGoogle Fontsの<link>
タグがhref
ではなくdata-href
になっていることが分かります。
またdata-href
の中身(=https://fonts.googleapis.com/...
の内容)がstyleタグに展開されています。
上の画像を見ていただくと分かりますが、フォントのデータ自体はhttps://fonts.gstatic.com
を読みにいっています。これは通常通りにGoogle Fontsを読み込んだときと同じです。
Font Optimizationの効果は?
Lighthouseで計測してみました。そんなに変わらんやろと思ってたところ……
Font Optimizationなし
Font Optimizationあり
えっ…………
そんな変わる?
「First Contentful Paint」や「Total Blocking Time」が1秒近く短縮されています。ブラウザのキャッシュを無効にして読み込むと、たしかに体感速度的にも少し早くなっているような…?
おわりに
Font Optimizationはかなり有益な機能だと思います。さらに.woff
データ自体も設定不要でセルフホスティングできるようになれば最高ですね。
(VercelにデプロイしたときにBandwidthを消費しまくって、プランをひとつ上げる必要が出てくるかもしれませんが)
ちなみに
今見ているZennではすでにFont Optimizationが有効になっています。
Discussion