Next.jsのISR + Rest APIを使ってみて

本日 (2021年3月8日)にUU-Circlesを公開いたしました!

参考 UU-Circlesを見るUU-Circles

Next.jsのISRとは

参考記事:【Next.js】CSR,SSG,SSR,ISRがあやふやな人へざっくり解説する

revalidateで指定した秒数以降にリクエストがきた時に、サーバー側でデータフェッチを再度行い、HTMLを再構築します。
一定期間ごとにサーバーサイドレンダリングを行うことで、高速なページ描画を実現しています。

【Next.js】CSR,SSG,SSR,ISRがあやふやな人へざっくり解説する

ISR + Rest APIを行なってみて

UU-Circlesでは、Next.js (ISR) + Rest API (Laravel) の構成で作成しました。

公開初日にして、各サークルの協力もあり、300以上のページを作成することができました!

ISRを使ってみて、メリットはレスポンスの高速化をすることができました。SSRよりも体感速度が確実に早かったです!

また、Next.jsがキャッシュを作ってくれるため、APIへのリクエスト数も確実に減少しました。リアルタイム性が少なくて良いUU-Circlesでは、ベストな選択肢でした!

公開初日に事故りました

下のように、60sごとにキャッシュを再生成するようにしてました。

これの問題点としては、revalidateを60sとすると、APIへのアクセスが60sごとに発生してしまいます (当たり前) 。

export async function getStaticProps(context) {
  const circleId = context.params.id
  const circle = getCircle(circleId)

  return {
    props: { circle },
    revalidate: 60, 
  }
}

ISRする際の考慮しなくてはならなくてならない点は、全てのリクエスト送信元はVercelのIPアドレスとなります。これにより誰がアクセスがしても、VercelがAPIコールすることになります。

これにより、Laravelのデフォルト設定の API limitationに引っかかりました。60sに60回しかAPIをコールできません。

対応策としては、

  • Next.jsのrevalidateの時間を増やす
  • LaravelのAPI limitationの値を増やす (RouteServiceProvider.php)
    /**
     * Configure the rate limiters for the application.
     *
     * @return void
     */
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(600)->by(optional($request->user())->id ?: $request->ip());
        });
    }

上記のふたつを緊急でして、公開日を無事、乗り切れることができました!

ただ、ページが増えたときにどうしようという悩みがあります。また、同じ問題が起きそう。負荷テストしないとだめかも😢

Vercelのipの許可または、専用のトークンを発行して、許容リクエスト数を増やす必要がありそう。

開発時のISRの辛さ

動的ルート(ダイナミックルート)は考慮しなくてはならないことが多く、大変でした。UU-Circlesでは、動的ルートでは部分的に諦めるようにしました。

ISRでgetStaticPathの中でAPIと接続する(pathをしっかり指定する)と、build時にAPIへリクエストを送ります。ローカル環境では問題は無いのですが、GitHub ActionでのbuildやVercelでのbuildでもコールできるAPIが必要になります。

通常は問題ないのですが、APIとISRのコードをともに変更すると、ISRのビルドが出来なくなることがあります。APIを先にプレビュー用のステージングにデプロイするなどの工夫が必要になり、少々だるいです。

対応としては、開発のときのデプロイどうするか問題を減らすために、ISRのpathを空の配列にしておくことが楽になると思いました!パフォーマンスは少し諦める( ;_; )

感想

ISRを行う場合は、静的なルートで、リアルタイム性が少なくて済む時は積極採用すべき。動的ルートでは、開発のフローをしっかり作り込み、必要に応じて、getStaticPathpath を指定するようにすべき。ということになりました!

Nextjsは最高!

最後に

ぜひ、UU-Circlesを訪問してください!!!!!

参考 UU-Circlesを見るUU-Circles