Astro 7.2の目玉は、実験的な差分ビルド(experimental.incrementalBuild)だ。9月3日に出た7.3がプレビューサーバー周りの小改善にとどまったのに対し、7.2のこの機能は静的サイト生成の弱点そのものに手を入れている。
仕組み: モジュールグラフのハッシュとcacheKeyの二重照合
有効化すると、Astroは事前生成ページごとに二つの指紋を比べる。一つはそのページを構成するモジュールグラフ全体(テンプレート、レイアウト、コンポーネント、アセット、依存パッケージ)のハッシュ。もう一つはgetStaticPaths()が各ルートに対して返すcacheKeyだ。両方が前回ビルドと一致したページだけ、再レンダリングを飛ばして前回の出力を使い回す。キャッシュはnode_modules/.astro/に置かれる。
つまり「コードが変わっていない」だけでは不十分で、「そのページが依存するデータも変わっていない」ことを開発者側がcacheKeyで表明する必要がある。データの鮮度管理をフレームワークではなく利用者に委ねる、明示的な設計になっている。
コンテンツコレクションとの相性
content/配下のMarkdownやMDXからページを生成する構成では、ローダーが各エントリに付けるentry.digestをcacheKeyに使うことが推奨されている。エントリの内容が書き換わればdigestが変わり、そのページだけが再生成される。記事の追加・修正が中心で、大半の過去記事は不変、というブログやニュースアーカイブ型のサイトが、この機能の想定する主な対象だ。
現時点の制約
getStaticPaths()経由でcacheKeyを返すページしか対象にならない。トップページのような単独の静的ページは毎回レンダリングされる。build.concurrencyが2以上のとき、キャッシュは無効化され、警告を出して全ページを再生成する。並列ビルドで時間を稼いでいたプロジェクトは、どちらを取るか選ぶことになる。- 実験フラグであり、キャッシュの持ち回り方(CIでの
node_modules/.astro/の永続化など)は自分で組む必要がある。
大規模サイトにとっての意味
数百〜数千ページある静的サイトでは、1記事直しただけでも毎回全ページを作り直すのが常態で、デプロイのたびに数分待つことになりがちだった。Next.jsのISRやEleventyの一部プラグインが実行時・ビルド時のキャッシュで対処してきた領域に、Astroもビルド時キャッシュという形で参入した格好だ。ISRのようにリクエスト時にページを差分生成するのではなく、あくまでビルド工程内でのスキップである点は、output: "static"構成を崩さずに済む利点でもあり、初回デプロイやキャッシュ破棄時のコストは変わらないという限界でもある。
実験段階なので本番の常用は早いが、ビルド時間がリリース速度の足かせになっているコンテンツサイトは、cacheKeyをどう設計するかだけでも今のうちに考えておく価値がある。機能の詳細はAstro 7.2の発表(https://astro.build/blog/astro-720/)と実験フラグのドキュメントにある。