1年以上前だけど、本番環境でNuxt.jsの静的生成(SSG, static site generation)を利用した。
案件に手を付けた頃の自分が分かっていたら楽になったであろうことをまとめてみる。
前提
- 要件は、SEO(OGP対応など)が必要、更新頻度は1日1回で十分、であったので、静的生成を選択
- 処理の流れ
- GitHubへのpushでCD起動
- CDサーバはWebAPIサーバにアクセスしつつ、静的生成
- 生成後、ストレージにアップロード
- CDNを通じて公開
- 生成対象サイトのページ数は10,000程度
生成時間に関わるパラメータ設定
concurrency
(同時実行数) と interval
(同時実行間の休憩時間)
- デフォルトの設定で動かすと、静的生成時にアクセスするWebAPIサーバのスケーリングが間に合わず、エラーが多発した。
- 具体的には、静的生成をAWS CodeBuildで、WebAPIサーバをAWS ECS(Fargate)で運用していた。
- 実行時間が短いほど、リリースやり直しなどがしやすく保守性が上がるので、ちょうどいい時間を見つけたいところ。
- 運用コストは抑えたいのであまりスケールさせたくないが、少なすぎると生成が遅すぎて使えない、という間でバランスを取るべく、
スケーリングのしきい値と、concurrency
interval
の値を調整しつつ、速さとスケール台数の少なさのバランスが取れたところを見つけていった。
nuxt generate
では --fail-on-error
オプション必須
Nuxt - コマンドと開発 - エラー時の失敗(Fail on Error)
- 失敗しても正常終了扱いになってしまうので、CDを利用している場合に不完全なリソースをリリースしてしまいかねない
- なお、終了するのは、全てのroutesの生成後なので、10,000件あれば全部終わってから。
- この挙動が不便だったので、エラーがあればその時点で終了できるようなプルリクを出した。devにはマージされてるようだ
crawler
オプション
Nuxt - generate プロパティ - crawler
Nuxt v2.13 以降、Nuxt には相対リンクをクロールし、クロールしたリンクに基づいて動的リンクを生成するクローラーがインストールされています。
- (曖昧な記憶)
- 現在は相対リンクのみのようだけども、外部へのリンクについてエラーが多発した記憶があり、
false
にして、生成対象URLに必要な情報をWebAPIで取得してroutes
オプションで設定して、利用していた。
- 現在は相対リンクのみのようだけども、外部へのリンクについてエラーが多発した記憶があり、
- 案
-
exclude
オプションと組み合わせて、true
のままで利用するといいかも。
-
ちょっと余談(AWS)
Nuxtそのものからはやや離れるけど、AWSでこの静的生成〜デプロイを行ったのでそれに関するメモ。
デプロイ
- 当時はまだAmplifyもなく、このページで案内されているのも「AWS と S3 + CloudFront」の方だけだった。
- この通りにgulpを利用していたが、静的生成が終わったあとのデプロイ時間が長いのがネックだった。
- 方法を検討・検証した結果、 AWS CLIを利用するのが高速と分かった。(2倍以上早くなった記憶)
- コマンドの詳細はうろ覚えだけども、こんな感じ
aws s3 sync --delete [local_dir] [bucket_dir] && aws cloudfront invalidate [Distribution_ID]
- コマンドの詳細はうろ覚えだけども、こんな感じ
URL末尾の処理
-
subFolders
オプションが関連- デフォルトの設定(
true
)を前提として。
- デフォルトの設定(
- S3にデプロイしてCloudFrontから参照すると、以下の3パターンのURLでアクセスできてしまう
- /page
- /page/
- /page/index.html
- SEO上の懸念(重複ページ、アクセスの分散)があるのでまとめたい
- CloudFront Functionsで末尾を統一するようリダイレクトする処理が必要
振り返りと今後にむけて
-
WebAPIの設計は改善の余地があったなと思う
- SPA的な挙動が許される箇所を分離すればよかった
-
運用コストは下がるし、サーバが落ちるリスクも下がるし、要件が許せば静的生成を使っていきたい。
- ログイン機能が必要な箇所があっても、その部分だけSPAにすればいけるはず
- NextjsのようにISR対応が進むとより嬉しい