👋

Next.js(app router)での最適化について

2023/09/12に公開

TL;DR

公式ドキュメントを読もう!
https://nextjs.org/docs

わかったこと

3種類のキャッシュと初期描画かどうか、Static RouteかDynamic Routeかどうか、という軸がある。

  • 3種類のキャッシュがある
    • Router Cache(client, in memory)
      • ナビゲーション体験を向上させる(ヌルヌル遷移)
    • Full Route Cache(server, persistent)
      • 初期描画速度を向上させる
      • serverでの描画コストを削減
    • Data Cache(server)
      • db負荷を軽減

※in memory cache... データはブラウザを閉じたりパソコンの電源をオフにすることで消滅する。データの永続性なし、揮発性。
※persistent(持続性)... データの永続性あり。
https://zenn.dev/kaa_a_zu/articles/f1430cf681b185

Static Routeはデフォルトでserverで描画後のRSC PayloadとHTMLがcacheされる。
Dynamic Routeはリクエストごとにserverで描画されてcacheされない。

Next.jsのデフォルトの挙動であるStatic RenderingからDynamic Renderingに自動で切り替わる条件


https://nextjs.org/docs/app/building-your-application/caching#dynamic-functions

これらの

  • Dynamic Functions
  • Segment Config Options
  • cacheを使用しないfetch

などがあるとNext.jsのデフォルトの挙動であるStatic RenderingからDynamic Renderingに自動で切り替わる。でStatic RenderingされたrouteをStatic Route、Dynamic RenderingされたrouteをDynamic Routeと呼んでいるのだと思われる。

最適化って何が嬉しいのか

とにかくこのような挙動を認識することが最適化の第一歩になると思う。
キャッシュを活用して最適化すると以下の回数やコストを減らしつつユーザーが待つ時間も最小限にできるのだと思われる。サービス運営側は運用費を抑えられるし、ユーザーはストレスなくサービスを利用できる。win-winだと思う。

  • serverへのリクエスト(Router Cache)
  • serverでの描画計算(Full Route Cache)
  • dbアクセス(Data Cache)

ユーザーはRouter Cache -> Full Route Cache -> Data Cacheの順に有効なキャッシュがあるかを確認していく、そしてFull Route CacheとData Cacheはserverにキャッシュされているので複数のユーザー達の間で共有される。だから記事をサービスの運営が1週間に1個投稿していくのを例に考えてみると、まず最初の1人が記事のurl(Static Rendering)にアクセスすると、 Router Cache(最初の一人目のパソコンのメモリー上),Full Route Cache(server上),Data Cache(server上)これら3つのキャッシュが生成されて、同じ記事への2人目のアクセス時にはRouter Cache -> Full Route Cache❗️ -> Data Cacheの流れのFull Route Cacheでキャッシュがヒットして描画済みのRSC PayloadとHTMLが返されるので、serverで描画するコストもdbアクセスも2人目以降は基本的に行われないということになる。

記事の更新などに合わせて以下の画像のようにdataの再検証などを行うことでdata cacheを無効にする -> server上でcomponentが再レンダリング Full Route Cacheが新しいデータを元に生成されキャッシュされる -> Router Cacheもそれに応じて無効になる

こんな感じでdata cacheに働きかけることでその変更がFull Route Cache -> Router Cacheに反映されていくようです。

この原則に照らして考えると上記の挙動はとても自然だなと感じました。
https://ja.wikipedia.org/wiki/信頼できる唯一の情報源

※記事の投稿をトリガーにbuildはしない想定。

小話

なんかpage単位でNode, Serverless, Edge を選べるらしい。
https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes

ユーザーみんなでシェアできるコンテンツならServerless
ユーザーみんなでシェアできないコンテンツならEdge
とかにしていこうかなとか思ってます。

今回の記事でああじゃないこうじゃないとか色々意見が飛び交って、知らなかったことをみんなが知るきっかけになればいいなと思っているので気軽にコメントください!

今月中には.nextフォルダーを.gitignoreから外して動かしながら挙動確認をしたいです。

ではまた明日!

Discussion