【前編】何が変わる?akfmさん、Quramyさんに聞く Next.js v15アップデート解説 #フロントエンドの未来

Connpass詳細はこちら

アーカイブはこちら

2024年09月25日、株式会社overflowが主催するイベント「何が変わる?akfmさん、Quramyさんに聞く Next.js v15アップデート解説」がオンラインにて開催されました。

ahomu氏:モデレーターで参加しているahomuと申します。プロフィールに関しては書いてある通りです。登壇者の紹介です。

akfm氏:akfmと言う名前でよく活動をしています。佐藤昭文と申します。フロントエンドを中心に活動していて、Next.jsの話をよくZennで記事にしたり本にしたりして書いています。

あとはRust、テスト、アジャイルが好きです。よろしくお願いします。

Quramy氏:Quramyと申します。僕もフロントエンドをやっています。資料には書いていませんがあっきーさんの同僚でもあります。フロントのアプリを作る傍らで、テスト回りを快適にするためOSSなどを作って公開するのが好きです。よろしくお願いします。

ahomu氏:今2人は同じチームで同じプロダクトを開発している状態ですか?

Quramy氏:所属は一緒ですが、いろいろなプロジェクトのお手伝いをする立場なので僕とあっきーさんが同じ現場の経験は今のところありません。僕はあっきーさんと一緒に仕事したくてうずうずしていています。

akfm氏:私も一緒に仕事をしたいと思っていますが、Next.jsのv15や最近の動向について話したり、相談に乗ってもらったりしています。

ahomu氏:今日はお二人から社内で蓄えた知見をご紹介いただけるとのことで、とても楽しみにしています。

それぞれの発表にうつります。最初はQuramyさん。

Offers」では、エンジニア・PM・デザイナー向けにキャリア、スキル、働き方についての役立つイベントを開催しています。無料登録・ログインで、人気のイベント動画は今すぐアーカイブ視聴可能です。動画を視聴して、最新の技術トレンドや実践的なノウハウを手に入れましょう!

【限定配信】アーカイブ動画を今すぐ視聴する!

LT:App Router 悲喜交々

Quramy氏:僕は社内のいろいろな案件をお手伝いしに行くことがメイン業務です。Next.jsのApp Routerを使う案件のリリースが今年の1月くらいにあったので、去年の6月からキリのいい今年の年度末くらいまで携わっていました。

今日はv15がテーマですが、どちらかと言うと、v13、v14の話をあっきーさんの前座としてお話しできればと思います。

今日はそんなに長くないのでかいつまんでとはなりますが、今年の4月にも同じ案件でApp Router使ってどうだったかの話をしているので、もしより詳細が気になる方は資料を参考にしてもらえればと思います。

アジェンダとしては、まずはApp Router開発で辛かったこと、その上でApp Routerを採用してよかったことの2本立てでお話しようと思います。

App Routerで苦しんだこと

早速苦しんだこと・辛かったことです。

キャッシュ周りは特に大きなポイントだと思います。

白い表は、Next.jsのApp Routerにさまざまなキャッシュがあるという話と関連しています。

Pages Routerを思い返すと、こんなに多くのキャッシュはありませんでした。App Routerになってからキャッシュが増え、それに対する向き合い方にかなり苦労した記憶があります。

特にNext.jsのv14やv13では、先ほどのキャッシュがデフォルトで強力にオンになっている状態から始まっています。自分のプロジェクトで必要十分な最適化を行う中で、そこまで強力なキャッシュはなく、むしろキャッシュの活かし方よりも殺し方を研究したり、勉強したりすることになりました。

例えば4つあるうちの真ん中の2つは(Data Cache、Full Route Cache)サーバサイドでPersistent(永続化)されるデータのキャッシュと、HTMLやRSC Payloadの画面のキャッシュのようなものです。

自分の案件でも、キャッシュのヒットレートが上がらなさそうだと感じ、一度作ってもほとんど参照されないこともわかっていました。むしろ、表示してはいけないタイミングで表示されて障害になるリスクの方が大きいため、意図的にオプトアウトしていました。

もう一つ、一番下のRouter Cache だけ、場所がブラウザになるin-memoryキャッシュです。以前自分のブラウザが表示した画面を覚えていて、それを高速に切り替えるイメージです。これはオプトアウトできずに、サーバアクションから殺せる関数を読んで殺す手段が与えられています。

そのような手段を使って注意深く殺していきました。

あっきーさんのこの後のお話で詳しく触れられると思いますが、キャッシュのデフォルトの挙動がv15で大きく変わるため、キャッシュを殺すために苦労した人にとっては、嬉しい変更になるかもしれません。

困ったことを一つ一つ挙げるときりがありませんが、v13やv14をアーリーアダプト気味に使っていたため、問題に直面することが多かったです。

オブザーバビリティ系のツールと連携しようとしたら、期待した挙動にならないこともありました。また、さきほどお話ししたRouter Cache があるはずなのにない状態で「ドキュメントと違う挙動をしている」ケースやNext.jsの機能でIntercepting RoutsやParallel Routesなど凝った画面……1個のレイアウトの中に複数のルートのポイントが入っているようなパターンのUIでは細かい不具合がいくつかありました。

ここに書いているものは、今試すと大体修正されているものばかりですが、早めにプロダクションを入れようと思ったばかりにこら辺で苦しんだ事実がありました。

それでもApp Routerをやっていてよかったと思ったことがあります。

App Router 採用してよかったと感じたこと

一番はReact Server Componentsがフルに使えることです。React Server Componentsに寄り添ったarchitectureで、自律的にData Fetchができることがとてもうれしい部分です。

Pages Routerと比較してもServer Componentsに直接Fetchや極端にはDBの参照みたいなものが書けますし、Server Actionsを使えばタイプスクリプトのコードを書いているように非同期にデータを更新することも可能です。

Data Fetchや取得更新まわりが気持ちよく、自分のやりたいことがそのままコードに落とせる感じがとても気に入っています。

Next.jsで考えると、App RouterではなくPages Routerと呼ばれていた頃のデータの取得方法は、Nextが組み込みで用意していたもので、古くはgetInitialPropsでした。少し後にgetServerSideProps(SSR用)、SSGで使われるgetStaticPropsもありました。

それらを使ってデータの取得をするのがNext Wayで、これらはどれもページコンポーネントに紐づいて書くstatic関数なんです。

あるページのツリーが必要とするデータはその手前のページのgetServerSidePropsやGIPで取得して、そこで取得したものを下のプロパティに流し込んでいくことしかできず、この部分が嫌いでした。

一方でRSCというarchitectureがもたらした非同期Server Componentで考えると、これがページの頂点である必要がないので、どこでも好きな所から必要なデータを取ってこられます。

Componentも必要なデータを取ってくることがRSCによって実現できるようになりました。

これが先ほど言った「自律的な」という心のような部分で好きなところです。

Componentが自分に必要なものを持ってくる、そんな書き方をしてもRSCのおかげでパフォーマンスが損なわれないんです。

Nextとは関係なくGraphQLをずっと使っていますが、GraphQLもこれと同じ属性が備わっているので、GraphQL好きにはものすごくうれしい部分です。

この辺りも好きなところで、自分のブログや動画のネタにもしているのでそちらも読んでいただければと思います。

嬉しかったことその2ですが、クライアントバンドルがぐっと減ります。

これは先ほど紹介した案件をブラウザのパフォーマンス測定ツール「Lighthouse」を使って測った点数です。先ほど少し言った通りNextのキャッシュはあまり生かさず、Data CacheやFull Route Cacheを殺した状態で測定していますが、90点台という割と実用的な点数が出てくれています。

この点数だけではパッと分かりませんし、別のプロジェクトなのでフェアな比較ではないかもしれませんが、Pages Routerでやっているような案件と比較するとオーダーで違う程度にinitial loadのJavaScriptで差が出ます。

気を使って実装したわけではありませんが、素直にデフォルトのServer Componentの世界で実装するときちんと小さくなり、そこそこ良い点数が出るのだなと感じました。

フレームワークに従って実装するってすごいと思いました。

ahomu氏:ありがとうございました。

では続きまして、あっきーさんよろしくお願いいたします。

LT:Next.js v15.0.0-rc.0 キャッシュのデフォルト挙動改善とPPR

akfm氏:Next.jsのv15のRCがリリースされていますが、今回は初めに出たRC.0についてお話しします。今後、RC.1などがリリースされると思いますが、内容が変わる可能性があるため、今日はRC.0にフォーカスしてお話ししたいと思います。

v15のRC.0の更新内容で、一番大きいトピックとしてよく出てくるものが、React19サポートです。

v15.0.0- RC.0でサポートする話で進んでいましたが、Boomer Fetchingと呼ばれるReact19で他ライブラリとの使い方の兼ね合いが問題になってしまって、今React 19のリリースが止まっている状態です。

最終的に以降のRCでは「React 19を待たない」と変更されたので、v15がリリースされる際にはReact 19のサポートがなくなる可能性があります。代わりにキャナリーか何かのサポートが入るのかなと思っています。

使い勝手は変わりませんが、React19のメジャーリリースを待たずにv15が出ると予測ができます。

ややこしい話から始めてしまいましたが、その他の機能としては、複雑だったキャッシュ周りのデフォルトが一部変更になったり、PPR(Partial Pre Rendering)機能のオプションが用意されたり、next/afterというフックが用意されたりなどなどいろいろあります。

細かいことは抜きにして、今日僕が特にお話したいことはこの2点です。

・キャッシュのデフォルトを一部変更

・PPRのincrementalオプションが追加

この2つがv15のRC0では一番大きな注目すべきトピックだと思うので、ここら辺を今日は持って帰ってもらいたいなと思い、お話していきます。

cache

キャッシュにはいろいろあります。

App Routerのキャッシュのお話はややこしいので、丁寧にお話しします。

一つ目が関数の戻り値としてフェッチなどをメモ化する「Request Memoization」についてです。これはメモ化なので、自動でメモされると思ってもらえればいいと思います。

2番目「Data Cache」はFetchの結果をサーバ側でキャッシュします。ひとつ目はメモ化なのでリロードするたびに破棄されますが、「Data Cache」はデータを共有するサーバ側のキャッシュになっています。

3番目が「Full Route Cache」です。これは従来からあるようなHTMLやApp Router、React Server ComponentsならではのRSC payloadというジェイソンやHTMLなどのフォーマットの一種のRSC payloadという独自のフォーマットのキャッシュです。

4番目がクライアントサイドのキャッシュ「Router Cache」です。

今回変更が入る「Data Cache」「Full Route Cache」「Router Cache」が、どのように変わるのかがミソとなっています。

v14以前は「Router Cache」のデフォルト設定が30秒から5分と長めでした。そのためクライアントサイドのキャッシュが予期せずに残っていることがあったり・なかったりしてややこしいことがありました。

「Data Cache」はデフォルトでキャッシュされる仕組みが実装者からパッと見えづらく、混乱の種となっていました。

「Full Route Cache」では、Pages Routerで従来のAPIツールのような「Router Handler」のGETを裁くハンドラーがキャッシュ可能で、デフォルトでキャッシュされる仕組みでした。そのため、ページやレイアウトもデフォルトでキャッシュされていました。

基本的に総じてキャッシュがデフォルトで強く有効になっていて、割と初見殺しで初学者に優しくない状態でした。

v15ではこのキャッシュの部分が変更され、「Router Cache」はデフォルト0秒になりました。最初を気にする必要がなくなり、自分で最適化したければオプトインすればよくなりました。

「Data Cache」もフェッチのデフォルトが"no-store"つまりキャッシュされない形に変更されました。

「Router Handler」でのGETもデフォルトでキャッシュされなくなり、基本的にキャッシュのデフォルト値が弱まりました。

初見殺しの部分が減ってきたところが、v15での変更の大きな点だと思っています。

初見殺しという言葉を使いましたが、これはずいぶん前から分かっていたことでした。「なぜもっと早く変更しなかったんですか」という意見も出てくると思いますが、ここに関しては、コアチームのJimmy Laiさんがツイートで説明しています。

簡単に言うと、デフォルトのキャッシュの挙動変更は去年の11月に始まっていましたが、どのようにパフォーマンスを損ねないで変更するかが問題でした。

Next.jsは哲学としてデフォルトで高いパフォーマンスを実現できることにすごく重きを置いているので、デフォルトのパフォーマンスを損ねるような変更はしたくないという判断があったのです。

これをこれから出てくるPPRが解決しました。

PPRがデフォルトになると、高いパフォーマンスを維持したままキャッシュのややこしい部分を減らす考えに至ります。PPRは現状エクスペリメンタルなのですが、実装もだいぶ進んできて、今後デフォルトになることが想定されます。

実装が進んで、設計の見直しも減ってきたので、Next.jsはPPRの方向に進んでいく方針が固まり、設計も固まり、デフォルトのキャッシュを変更してもいい段階に来たという判断があったのでこのタイミングでの変更となりました。

PPR

PPRはPartial Pre Renderingの略です。

これを理解するには、まずApp RouterのStatic RenderingとDynamic Renderingという概念を理解する必要があります。

Static RenderingはSSGやISR相当で、ページを生成して必要ならrevalidateするものです。

Dynamic RenderingはSSR相当、リクエストごとにレンダリングできるような仕組みです。

厳密には少し違う部分もありますが、簡略化するとこういうことです。

PPRの世界ではこの2つが混在できます。具体的に言うと、ECサイトで紫の部分はStaticRenderingです。

そのためビルド時に生成したりしますが、カートやレコメンドはユーザーごとに違うUIパーツだと思います。これをサスペンスでくるむと、外側はStaticのまま部分的にDynamicなコンポーネントをレンダリングすることができます。これがPPRです。

今までは静的か動的か2択しかなかったのもが、2つをうまく組み合わせて「基本的には静的で部分的に動的」ができるようになりました。

PPRは「可能な限りStaticに、部分的にDynamicに」というレンダリングを可能にするモデルです。

現状この機能はエクスペリメンタルですが、パフォーマンスとシンプルな設計を両立できるため注目されています。また、僕らとしてもSuspenseでDynamic Renderingを簡単にくるむだけで済むので、とても嬉しい機能です。しかしNext.js側の実装はとても大変です。

PPRは、去年v14が発表されてから進んでいて、この1年ほどでバグ修正や内部テストが進められ、徐々に安定してきている段階です。

今までページ単位で設計を考えなければならなかったのが、Quramyさんもお話していたように、"コンポーネント思考"や"自律的"なコンポーネントごとに小さく実装できる、よりReactらしい設計が実現できる機能だと思います。

ただデメリットとしては、CDNとの相性が悪く、Status Codeに依存した監視ができない点などがあります。これらの点に注意すれば、ユーザーにとってもメリットが多く、私たちにとっても優れたDX(開発者体験)を享受できる機能だと思います。
詳しくは記事にもまとめているので、興味があればご参照ください。

https://zenn.dev/akfm/articles/nextjs-partial-pre-rendering

PPR incrementalオプションではページ単位でPPRも有効になります。

まとめ

まとめとしては、キャッシュのデフォルトが変更されて初見殺しが減ってきました。

PPRの実装が進み先ほどのオプションが有効にできることになったことで、今まではPPRを有効にすると全ページで有効になっていたのが、V15からはこのフラグで「このページだけ有効」ということができるようになり段階的に導入することも可能になりました。

V15ではApp Routerがより初学者にやさしくシンプルな設計を実現できるようになると個人的に期待しています。

最後、直近の動きも話したかったのですが、時間もだいぶオーバーしてしまったのでこの辺でいったん切りたいと思います。

ありがとうございました。

ahomu氏:私自身v14のApp Routerと戯れた経験がありましたが、V15から入りたかったなという気持ちになってきました。

akfm氏:そう思えるような嬉しい変更がたくさんあるので、僕としてもV15から(そろそろ触ってみようかな)と思う方が増えたらいいなと思っています。

ahomu氏:改めてアッキーさんありがとうございました。

Xにも感想がたくさん来ていますので、運営で集約して質問などを拾っていきたいと思います。

【後編はこちら】


Offersエージェント」では、業界で活躍するプロフェッショナルがあなたの転職を徹底サポート。CxO経験者を含む現役エンジニア・デザイナー・プロダクトマネージャーが在籍し、職種に特化した専門的なアドバイスをご提供・非公開求人の紹介も可能です


この記事をシェア

関連記事


副業・フリーランス

プログラミング

インタビュー

デザイン

お金

採用・組織

イベントレポート

転職