Open37

Next.jsでReact18の機能を試してみる

nus3nus3

Next.jsでReact Server Componentsを使う作業ログ

nus3nus3

サンプルリポジトリだとビルドを実行すると

Page                                       Size     First Load JS
┌ ○ /                                      1.05 kB        84.5 kB
├ ○ /404                                   194 B          79.5 kB
├ ○ /csr                                   632 B          90.3 kB
├ ℇ /item                                  2.24 kB         114 kB
├ ℇ /rsc                                   2.72 kB         111 kB
├ ℇ /slow                                  2.66 kB         111 kB
└ ℇ /ssr                                   2.87 kB          89 kB
+ First Load JS shared by all              79.4 kB
  ├ chunks/framework-a87821de553db91d.js   45 kB
  ├ chunks/main-6f7a5663a306f0a0.js        32.7 kB
  ├ chunks/pages/_app-9538641435026bd3.js  824 B
  └ chunks/webpack-9b312e20a4e32339.js     836 B

ℇ  (Streaming)  server-side renders with streaming (uses React 18 SSR streaming or Server Components)
○  (Static)     automatically rendered as static HTML (uses no initial props)

ℇ (Streaming) server-side renders with streaming (uses React 18 SSR streaming or Server Components)になるけど、runtimeに 'nodejs'で試すと、この形式にはならない

nus3nus3

nodejsだとReact Server Componetsを使った際に画面が描画されなくなるので
とりあえずサンプルリポジトリと一緒のruntime: 'edge',を指定する

nus3nus3

ドキュメントに記載されている"next": "canary",を使う場合は
edgeの部分をexperimental-edgeに指定することでReact Server Componentを使用できる

module.exports = {
  experimental: {
    runtime: 'experimental-edge',
    serverComponents: true
  }
};
export const config = {
  runtime: 'experimental-edge'
};

nus3nus3

yarn devは動かないけど、yarn buildしてからyarn startすると動く

nus3nus3

server-side renders with streaming (uses React 18 SSR streaming or Server Components)
ってあるけどSSR streamingする場合とServer Componentsになる場合の違いはなんじゃろ

nus3nus3

pageにgetServerSidePropsを定義してそこでSuspense読んでもStreamingにはならない

nus3nus3

ssrのpageに

export const config = {
  runtime: 'experimental-edge'
};

するとstreamingになる

基本的にSSRでもCSRでもserverコンポーネント使ってるページでも上のconfigをexportすればstreamingとして扱われる

nus3nus3
  • csrのページでconfigをexportするとyarn devでもSuspenseの挙動を確認できる
  • ssrはドキュメントに記載されてる通り、yarn devだとエラー
  • server componentsはそもそもyarn devでは動かない
nus3nus3

Streaming SSR

  • Suspenseで囲まれたコンポーネント以外は先にSSRしてHTMLを返す
  • Suspenseで囲まれたコンポーネントのレンダリングはSuspense内でthrowされたPromiseが解決されるとサーバー側からプッシュされて、再レンダリングされる
    • Promiseが解決されるとHTMLが追加される
  • これにより初回のHTMLの描画は向上され、Suspense内のコンポーネントは後続のサーバー側からのプッシュで描画される
nus3nus3

Layouts RFCをざっくり読む
https://nextjs.org/blog/layouts-rfc

nus3nus3

Next.jsの新しいLayoutsはReact18の簡単に採用できるように設計されている

nus3nus3

Next.jsでは新しいlayoutの機能を実装することで、今よりも、よりパフォーマンスを向上させたり、リッチなアプリケーションを簡単に作れるようになりたい

nus3nus3

新しい機能のルーティングはpagesじゃなくてappでできるようになる

後方互換性があるように今までの状態で使いたい場合は引き続きpagesを使うと良い

nus3nus3

appディレクトリ内でのルーティングはファイルではなくフォルダーが基本になる

いままで、拡張子の設計を変える以外にpages配下にルーティング用のファイル以外を置く方法がなかったが、appディレクトリ内はルーティングが基本、ディレクトリになるのでテストやStorybookなど別のファイルも置けるように

nus3nus3

appディレクトリ内でlayout.jsを定義すると画面遷移で再レンダリングされない(状態管理を保ったまま)のコンポーネントを定義できる

nus3nus3

このlayout.jsはappディレクトリ内の構造のようにネストすることができる

nus3nus3

いままでpages配下に配置していたpage用のファイルはappディレクトリ内ではpage.jsで定義する

nus3nus3

appディレクトリでつくる新しいルーティングはReact18の機能を活用して実装されている

nus3nus3

appのディレクトリないのファイルはデフォルトではServer Componentsを使ってサーバーサイド側でレンダリングされるようになる

nus3nus3

app内のlayoutとpageコンポーネントはサーバーサイド、クライアントサイド、その両方のどれでも選択できる

nus3nus3

いままでNext.jsでは、いつ、どこでレンダリングするかは、Next.jsのデータフェッチの関数を使用することで選択していた

appディレクトリでは、レンダリングの方式はデータフェッチとは切り離され、コンポーネントレベルで選択されるようになる

nus3nus3

layoutファイルではgetStaticPropsとgetServerSidePropsが使用できる