AstroではGoogle Fontsを直接利用しない方が良いかもしれない
Astro が stylesheet を巻き上げる
デプロイ後のサイトで、各ページの初回アクセス時に<link rel="stylesheet">
要素が全てhead
要素の先頭に巻き上げられる挙動を確認した。
初回アクセス時とリロード時で、次のようになっていた。
初回アクセス時:
<!DOCTYPE html><html lang="ja"> <head> <!-- Some Comment 1--> <!-- Some Comment 2--> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" /> <link rel="stylesheet" href="/_astro/some-styles.css" /> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <!-- 中略 --> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <style> /* ... */ </style> <style> /* ... */ </style> <style> /* ... */ </style> </head></html>
リロード時:
<!DOCTYPE html><html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width" /> <!-- 中略 --> <!-- Some Comment 1--> <link rel="stylesheet" href="/_astro/some-styles.css" /> <!-- Some Comment 2--> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" /> <!-- 中略 --> <style> /* ... */ </style> <style> /* ... */ </style> <style> /* ... */ </style> </head></html>
Google Fonts の巻き上げによる影響
Google Fonts で埋め込みコードを取得すると次のようなコードが得られる。
<link rel="preconnect" href="https://fonts.googleapis.com" /><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap"/>
このコードではスタイルシートの読み込みだけではなく、スムーズなフォントの読み込みやキャッシュの利用が出来るように事前に接続を確立するための記述が 1、2 行目で行われている。
しかし、ここで 3 行目のスタイルシートの読み込みのみが巻き上げられて最上位に来てしまうと、HTML は基本的に先頭から解釈されていくため、1、2 行目の指定が無意味になる可能性がある。
調査と原因の推測
公式で明示的に言及している箇所は見つけられなかった。
ただし、Astro のスタイリングに関するドキュメントには、スタイルシートのカスケード順序についての記述があり、<link>
要素のスタイルは最も優先度が低くなるとある。これを叶えるために巻き上げている可能性が考えられる。
Astro の紹介する Google Fonts の利用方法 Fontsource
Astro のドキュメントでは、Fontsource経由での利用が紹介されている。
https://docs.astro.build/en/guides/fonts/#using-fontsource
import "@fontsource-variable/source-serif-4";
この方法では確かに最上位への巻き上げは行われない。なぜなら、ドキュメントのカスケード順序について記述によれば、Fontsource を利用する上での形式であるimported styles
は<link>
よりも優先度が高く<style>
よりも低いとあるためであり、仕様通りの挙動となっている。
Fontsource を利用する場合、Google Fonts の埋め込みコードにある事前接続相当の処理は、各フォント毎のスニペットに記載されていないため、次のドキュメントを参考にしてpreload
用の記述を追加することが望ましい。
https://fontsource.org/docs/getting-started/preload
import sourceSerif4 from "@fontsource-variable/source-serif-4/files/source-serif-4-latin-wght-normal.woff2";
<link rel="preload" as="font" type="font/woff2" href={sourceSerif4} crossorigin="anonymous"/>;
実際の影響
少なくとも、この現象を確認したサイトでは、Fontsource を利用したケースと比較して有意なパフォーマンス差は見受けられなかった。
そもそも、Google Fonts を直接する利用する元々の状態で、Lighthouse のパフォーマンススコアは 95 点以上を維持しており、巻き上げによる影響が実際にはない可能性も考えられる。
とはいえ、Google Fonts の読み込みが最上位に巻き上げられる挙動が意図したものとは思えないため、Astro においては紹介されている Fontsource を利用する方法が選択すると良いように思う。