Next.js(app router)での最適化について
TL;DR
公式ドキュメントを読もう!
わかったこと
3種類のキャッシュと初期描画かどうか、Static RouteかDynamic Routeかどうか、という軸がある。
- 3種類のキャッシュがある
- Router Cache(client, in memory)
- ナビゲーション体験を向上させる(ヌルヌル遷移)
- Full Route Cache(server, persistent)
- 初期描画速度を向上させる
- serverでの描画コストを削減
- Data Cache(server)
- db負荷を軽減
- Router Cache(client, in memory)
※in memory cache... データはブラウザを閉じたりパソコンの電源をオフにすることで消滅する。データの永続性なし、揮発性。
※persistent(持続性)... データの永続性あり。
Static Routeはデフォルトでserverで描画後のRSC PayloadとHTMLがcacheされる。
Dynamic Routeはリクエストごとにserverで描画されてcacheされない。
Next.jsのデフォルトの挙動であるStatic RenderingからDynamic Renderingに自動で切り替わる条件
これらの
- 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に反映されていくようです。
この原則に照らして考えると上記の挙動はとても自然だなと感じました。
※記事の投稿をトリガーにbuildはしない想定。
小話
なんかpage単位でNode, Serverless, Edge を選べるらしい。
ユーザーみんなでシェアできるコンテンツならServerless
ユーザーみんなでシェアできないコンテンツならEdge
とかにしていこうかなとか思ってます。
今回の記事でああじゃないこうじゃないとか色々意見が飛び交って、知らなかったことをみんなが知るきっかけになればいいなと思っているので気軽にコメントください!
今月中には.nextフォルダーを.gitignoreから外して動かしながら挙動確認をしたいです。
ではまた明日!
Discussion