【Next.js】unstable_runtimejsでhydrationを無効化し静的(MPA)化する
やりたいこと
Next.jsでSSG(Static Export)なブログを作成していると、サイト自体を完全に静的化したい時がある。
「完全な静的化」とは
どいうことかというと、Next.jsではSSGをしてもhydration処理のためにruntime-jsが実行される。例えHooksや<Link>
タグを利用したclient-side routingを利用していなくとも。
そのため上のようなjsファイルが読み込まれるわけだが、async
が指定されているとはいえサイズ的にはかなり膨大。
そこでNext.jsのJavaScriptを全て抜いて完全にMPAな(ピュアなHTMLのみの)サイトにしたい。
そもそもMPA化したい理由
- 初回アクセス時の表示速度を上げたい
- ブログの性質上、検索結果への直帰率が高いためclient-side routingが不要(SPAにする恩恵が少ない)
Next.jsを使わない手もある
ちなみに別のフレームワークやテンプレートエンジンを利用するという方法もあったが、下記の理由から断念した。
- tsxで書きたいのでEJSやPUGは候補外
- Reactを利用できるMPAフレームワークのAstroにも興味はあったが、単純に乗り換える手間がかかる
解決法
Next.js 12以下の場合
/pages
を利用している場合、静的化したいページのunstable_runtimeJS
をfalse
にするだけで実現できる。
Next.js 13以上(App Directory)の場合
App Directoryの場合unstable_runtimeJS
は使用できず、なおかつNext.js側でそういったオプションは用意されていない。
そこで、static export
で生成したHTMLから直接script
タグを削除する、という無理やりな方法で実現することにした。
1. npm-scriptsを実装
/bin/optimizeHtmlFile/index.js
のようなファイルを作る。
/out
下に生成されたHTMLファイルを全て取得- DOM操作ができる
jsdom
ライブラリを使いscript
タグを削除 - HTMLファイルとして再書き出し
2. build後に実行するよう設定
あとはbuild
後にそのnpm-scriptsを実行するようにpackage.json
に追記する。これでruntime-jsを全て無効化できた 🎉
参考