SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Next.jsの新しい概念を学ぶ

Next.jsの新常識「App Router」を学ぼう!

Next.jsの新しい概念を学ぶ 第1回

  • X ポスト
  • このエントリーをはてなブックマークに追加

 Next.jsは、ルーティングとサーバー処理を高度に協調させるためのフレームワークとして、デファクトスタンダードの地位を確かなものにしています。2023年5月5日に公開されたNext.js 13.4において、フレームワークの根幹であるルーティング機構を刷新する新機能が追加されましたので、今後のNext.jsはどんな世界観で扱えばいいのかを解説していきます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

対象読者

  • JavaScriptとWeb開発の基礎に理解がある方
  • Reactを用いたJavaScriptアプリケーション開発の経験者

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Ventura 13.4
  • Node.js 20.2.0/npm 9.6.6
  • React 18.2.0
  • Next.js 13.4.4

より直感的なルーティング、よりサーバーを活用したレンダリング

 Next.jsは、ReactでWebサイトやWebアプリケーションを作成するための、主にルーティング(画面遷移)に責任を持つフレームワークとして、デファクトスタンダードと呼ぶに相応しい立ち位置で使われるようになりました。2016年に登場し、ブラウザで動くだけなのが当たり前だったReactをサーバー側でレンダリングする(サーバーサイドレンダリング)というアプローチの先駆者として、この分野を牽引しています。ただ、時代の要請に応えたり、後発のフレームワークにインスパイアされた新機能を取り込んでいくうちに、ルーティング機構が複雑になるのが近年の課題になっていました。

 そこで、Next.jsチームは、Reactの次の時代を牽引すべく、フレームワークの根幹ともいえるルーティング機構を再設計しました。それがNext.js 13.4で安定版がリリースされたApp Router(アップルーター) です(図1)。

図1:App Routerのドキュメント
図1:App Routerのドキュメント

 App Routerには大きな特徴が2つあります。ファイルパスの使い方の刷新と、レンダリングにおけるサーバーの活用です。

ファイルパスの使い方を刷新

 まず一つ目として、ファイルパスの使い方の刷新です。フォルダ内のファイルパスでルーティングを決定する方式(file-system based router)であることは従来と変わりませんが、フォルダ名やファイル名の命名規則が大きく変わりました。

 その一環として、App Routerではトップレベルのフォルダとして pages/ ではなく app/ を利用します。App Routerという名前は、このフォルダ名に由来しており、従来のルーティング機構はPages Routerと呼ばれることになりました。

 Pages Routerでは、レイアウトと呼ばれる機構を後付けした際にAPIが複雑になってしまいましたが、App Routerではレイアウトを初めから設計に組み込んでいるため、直感的に扱えるようになっています。

サーバーをより活用したレンダリング

 二つ目としては、レンダリングにおけるサーバーの活用が挙げられます。ここでいうレンダリングとは、あるデータに基づいて、条件分岐や反復処理を行い、コンポーネントの構造を決定する処理を指します(必ずしもHTMLの生成は伴いません)。

 Pages Routerにも、画面遷移時にサーバー側でデータ取得を行う機能はありました。しかし、レンダリングまでサーバー側で請け負うのは、ページを直接リクエストする初期表示のときのみで、画面遷移後の(複雑な条件分岐や反復処理を含む)レンダリングや、ページ内の個別のコンポーネントによる非同期通信は、ブラウザ側に任されていました。

 一般論として、ブラウザの処理性能や通信の速度は、ユーザーの使っているネットワークやデバイスの性能に強く依存します。サーバーの性能はサービス提供者(この記事を読んでいるあなたも、おそらくそうでしょう)がチューニングしたりお金を払うことで向上させることができますが、ユーザーが個別の事情で型落ちのスマホや格安通信事業者を利用することに対しては、何の対処もできません。Pages Routerのアプローチでは、サーバー側で処理できる比率が頭打ちしやすかったのです。

 そういった課題もあってか、App Routerでは思い切った戦略が取られました。原則として、 全てのReactコンポーネントをサーバー側でレンダリングすることにした のです。通信も、条件分岐も、反復処理も、全てサーバーで行えば、ユーザーの環境によってパフォーマンスが落ちる要因を最低限にできます。

App Routerを支える技術「React Server Components」

 App Routerのレンダリング戦略を後押しするように、Reactというライブラリそのものにも、サーバーでレンダリングすることに特化した記法が追加されました。それが React Server Components(RSC)と呼ばれるコンポーネントです。厳密にはNext.jsではなくReact側の新機能ですが、初めての活用事例がNext.jsなので、Next.jsのドキュメントで詳細に解説されています。

 具体的には、リスト1のようなコンポーネントをサーバー側で事前に処理できるようになりました。

[リスト1]サーバー側で処理するためのReactコンポーネント
// (1)
export async function ArticleComponent({ id }) {
  // (2)
  const res = await fetch(https://api.example.com/articles/${id});

  if (!res.ok) {
    throw new Error('データの取得に失敗しました');
  }

  const data = await res.json();

  return (
    <article>
      <h2>{data.title}</h2>
      <div>
        {data.content}
      </div>
      {/* コメントがある場合だけコメント欄を表示する */}
      {data.comments.length > 0 ? (
        <div>
          <h3>コメント</h3>
          <ul>
          {data.comments.map((comment) => (
            <li key={comment.id}>{comment.author} {comment.text}</li>
          ))}
          </ul>
        </div>
      ) : null}
    </article>
  );
}

 Reactの経験が長い方にとっては、(1)のように関数コンポーネントをasync functionとして定義していることも、(2)のように関数コンポーネントのスコープ内で通信をしていることも、極めて奇妙なことに感じられると思います。

 当然ながら、このコンポーネントをブラウザで実行することはできません。サーバーで処理されて、通信や条件分岐や反復処理を終えた、最終的なビューツリーのデータだけがブラウザに送られます。このデータはHTMLではなくJSONLライクな独自形式になっており、軽量かつ柔軟にツリーを分割しながらブラウザに送信できるのですが、本記事の本筋ではないので、割愛させてください。

 さて、リスト1では最も特徴的な、async functionの直下で通信を行うコンポーネントを例に挙げましたが、Next.jsのApp Routerでは、リスト2のような素朴なコンポーネントも、Server Componentsとして処理されます。

[リスト2]素朴なコンポーネント
export function Text({ children }) {
  return <span>{children}</span>;
}

 ブラウザ側でレンダリングや状態管理が行われるコンポーネントは、明示的に「これはブラウザ側でレンダリングしてほしい」というおまじない(次回以降に解説)を記載したものだけになります。

 繰り返しになりますが、App Routerを利用すると、原則として全てのReactコンポーネントがServer Componentsとして処理されます。これは、従来のPages Routerや、シングルページアプリケーションでのReactと比較しての、最も大きな違いとなりますので、React経験者がApp Routerを学ぶ場合には、よく意識していただければと思います。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
はじめてのApp Router

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Next.jsの新しい概念を学ぶ連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17925 2023/07/05 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング