Next.jsからAstroにブログを移行してみた【SSGのパフォーマンスやビルド時間の比較など】
Next.js(13.4)の静的サイトジェネレーター機能を利用してコンテンツを生成していた当サイトだが、先日フレームワークをAstro(3.0)に乗り換えた。
移行には大体2・3日ほどかかったがその分得られたリターンも大きく、移行して良かったと強く思っている。
移行した背景
ページパフォーマンスの改善
直帰率が非常に高いので遷移時より初回アクセス時のパフォーマンスをより良くしたい、というのが一番の移行理由になる。
というのも当サイトのようなCRUD処理や認証といった動的な処理を必要としない個人ブログは、その記事を見たら関連記事などに遷移せず参照元に戻るユーザーが大半である(Google Analyticsで見ても当サイトの直帰率は80%以上だった)。
もちろんNext.jsでSSGしていた際に「SPAすご、ページ遷移サクサクや」となっていたのも事実だが、それは運営者だから感じることであって、基本的に訪問者はそこまでサイトを徘徊しないし遷移時のスピードもそこまで見ていないはず。
そこで初回アクセス後の遷移スピードという意味ではSPAは非常に魅力的だったが、そんな自己満足のためだけにそこそこ膨大なサイズのJavaScriptを読み込んでハイドレーションさせるのは割に合ってないのではと思い、どうせならより初回アクセス時のパフォーマンスを求めようということで思い切ってMPA化することに決めた。
ちなみに下記のようにNext.jsでSSGして生成されたHTMLからJavaScriptを引っこ抜くということも試したがbuild後のコードを無理やり整形するのも何だかなぁという感じだったので、大人しくAstroに移行することにした。
【Next.js】unstable_runtimejsでhydrationを無効化し静的(MPA)化する
トレンドな技術のサポート
Astroでは下記をお手軽に導入できることが非常に魅力的だった。
- View Transitions(View Transition API)
- Partytown
両者ともNext.jsで利用するとなると自前の実装が必要になる(v.13.4.19
時点)が、Astroはこういったトレンドな技術も率先してサポートしており、今後にも期待が持てそう。
【Astro】Partytownを利用してGoogle Analyticsを導入する
パフォーマンスの比較
ページパフォーマンス
Next.js | Astro | |
---|---|---|
1回目 | 98 | 100 |
2回目 | 95 | 100 |
3回目 | 100 | 100 |
PageSpeed Insightsでそれぞれ同じ記事ページを3回ずつ計測してみたが、Astro(移行後)は毎回100点を叩き出した。
元々SSGして静的にHTMLを配信しているだけだったのでスコアは非常に高かったが、
- ハイドレーションのためのJavaScriptが削除された
- CSSがインライン化されたことによりリクエスト数が削減された(圧縮後のCSSサイズが4KB未満の場合に限る)
されたことにより、より磨きがかかった形になる。
ビルド時間
当サイトの記事はMarkdown形式で記述しローカルでGit管理しているが、記事数が多い影響で毎回ビルドにそこそこ時間がかかっていた。
Next.js | Astro |
---|---|
62s | 50s |
が、上記のように移行後はかなり短縮されるという嬉しい結果に。
移行のためにやったこと
基本的には以下のようなNext.js(App Router)特有の機能を修正するだけ。
- ルーティング・データフェッチ
/app
ディレクトリを/pages
に置換- 各ページコンポーネント(
page.tsx
)をindex.astro
に書き換え generateStaticParams
をgetStaticPaths
に書き換え
<Link>
を<a>
に置換- SEO
- Metadata APIで出力していた
<head>
内の各タグを自前実装 sitemap.xml
の自前実装robots.txt
の自前実装
- Metadata APIで出力していた
- 各種Linterの設定を修正
というのもAstroではIntegrationとしてReactが利用できるので、既存の.tsx
ファイルはそのまま移行するだけ。さらに既存実装ではできるだけNext.jsに依存しないように書いていたため、そのおかげで各資材(記事や画像)は一切手を加えずに済んだ。
正直もっと大掛かりな移行になると思っていたが、「他フレームワークからの移行もしやすい」というAstroの前評判通りそこまで手間はかからず、非常に有難い限りである。