Server Components

サーバーコンポーネント

Server Components(SC)

Next.js 13.4は、次世代のNext.jsの安定版リリースで、App Routerという新機能が大きな変化として登場していますよね。このApp Routerは、React Server ComponentsとSuspenseを基盤として構築されています。

2023 年 5 月に安定版が出た Next.js v13.4 の App Router には、Server Components という機能が追加されました。クライアントに送信される JavaScript の量を軽減し、最初のページロードを高速表示することができます。JavaScript のバンドルサイズが削減された結果、パフォーマンスが高くなるイメージです。

さて、React Server Componentsって一体何なんでしょうね?

これを理解するために、ちょっとした例え話をしますね。イメージとしては、レストランのシェフが遠くのお客さんに料理を運ぶ代わりに、その場で調理を始める感じです。その結果、料理が冷めることなく、最高の状態でお客さんに提供できるんですよ。React Server Componentsは、この原理に基づいています。つまり、サーバー側でコンポーネントをレンダリングし、ブラウザには最終的なHTMLとCSSのみを送信するので、JavaScriptの負荷が軽減され、パフォーマンスが向上するわけなんですよ。

また、Next.js 13.4のリリースでは、新しいApp Routerが導入され、それによりアプリケーションのレイアウトをより柔軟に定義することが可能になりました。たとえば、従来のNext.jsでは、ページごとのレイアウトを定義するためには_app.jsというカスタムファイルを使う必要がありました。しかし、新しいApp Routerでは、レイアウトのコンポーネントを組み合わせて使うことが可能になり、また、データの取得をコンポーネントと一緒に配置することも可能になりました。この新しいルーターは、CSSのインポートやページの部分的なハイドレートなど、従来のNext.jsの制約を取り払う機能も提供しています。凄くないですか?

Next.js 13.4のServer Componentsの具体的な使用例としては、MakerKitというNext.jsとSupabaseを使用したSaaSのスターターキットがあります。MakerKitは、Next.js 13.4の実験的な"app"ディレクトリを使用して構築されており、React Server Componentsを活用しています。

MakerKitには、Stripeによる支払いやサブスクリプションのサポート、ユーザーのアカウント設定や組織作成を支援するオンボーディングフロー、組織の作成と編集、他のユーザーを組織に招待して役割を割り当てるチームメンバー、MDXを使用したブログとドキュメンテーションのジェネレーターなど、多くの機能が組み込まれています。

また、マーケティングの面でも、ConvertKit用のニュースレターサインアップフォームやReact.emailを使用したメールテンプレートなど、様々な機能が提供されています。

これらの機能を利用することで、あなたのNext.jsプロジェクトは劇的にパフォーマンスが向上し、開発の生産性も向上することでしょう。ただし、Next.js 13.4のServer Componentsはまだ実験的な段階にありますので、その点は留意してくださいね。

メリットを整理すると次のようになります。

  • パフォーマンスが向上する
  • 最初のページの読み込みが速くなる
  • JavaScript バンドルサイズが縮小される

サーバーとクライアントのコンポーネントを使用することで、開発者はクライアントサイドアプリの豊かなインタラクティブ性と、従来のサーバーレンダリングの高いパフォーマンスを組み合わせたアプリケーションを構築できます。

ただし、Client Component から Server Component を利用することが出来ません。ちょっと制約が厳しいところもありますね。

App Router 内のコンポーネントはデフォルトで Server Component になります。Client Component として動かしたい場合には "use client" をファイルの先頭で宣言します。

どのようなときに使うのか?

SC をどのようなときに使うのか?というと、データを取得したりバックエンド リソースに (直接) アクセスする場合です。

一方、Client Component(CC) は、useState、useEffect、useReducer など、ブラウザーのみの API に依存するカスタムフックを使用する場合に使います。

エラー

実際に、Pages Router で構築したアプリケーションを App Router に移行してみました。その結果、次のようなところでエラーが出ました。

  • useRouter(現在 router.events はサポート外)
  • getStaticPath / getStaticProps
  • Google Analytics
  • asPath は使えない
  • router.events は使えない

サポート外や使えないものは書き換える必要があるので、移行するときは注意が必要です。

クライアントコンポーネントよりも優れている理由

以下は、Next.js のドキュメントを意訳したものです。

以前はクライアント上の JavaScript バンドルサイズに影響を与える大きな依存関係が、サーバー上に完全に残ることでパフォーマンスが向上します。これにより、React アプリケーションの作成が PHP や Ruby on Rails のような感覚になりますが、UI のテンプレート化に React の力と柔軟性が備わります。

Server Components を使用すると、最初のページの読み込みが速くなり、クライアントサイドの JavaScript バンドルサイズが縮小されます。ベースとなるクライアントサイドのランタイムはキャッシュ可能で、サイズが予測可能であり、アプリケーションが拡大しても増えません。クライアントコンポーネントを通じてアプリケーションでクライアントサイドのインタラクティビティが使用される場合にのみ、追加の JavaScript が追加されます。

Next.js でルートが読み込まれると、初期 HTML はサーバー上でレンダリングされます。この HTML はブラウザで徐々に強化され、クライアントがアプリケーションを引き継ぎ、Next.js と React クライアントサイドランタイムを非同期でロードすることでインタラクティビティを追加することができます。

Server Components への移行を容易にするために、App ルーター内のすべてのコンポーネントはデフォルトで Server Components になっており、特別なファイルやコロケーションされたコンポーネントも含まれます。これにより、追加作業なしで自動的にそれらを採用でき、すぐに優れたパフォーマンスを実現できます。

Client Component(CC)

CC は、クライアント側の対話機能をアプリケーションに追加できます。'use client'ディレクティブを使用して、クライアントコンポーネントをオプトインすることもできます。Next.js では、それらはサーバーで事前にレンダリングされ、クライアントでハイドレートされます。