NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

Pages Router と App Router - Next.js の新旧ルーティングシステムの違いと使い分け -

本記事は  Reactウィーク  3日目の記事です。
📍  2日目  ▶▶ 本記事 ▶▶  4日目  📱

はじめに

こんにちは。先日配信されたPerfumeの最新アルバムがかっこよくて、最近なかなか寝付けなくなっているNRIネットコムの小畑です。

App Routerを触り始めてからちょうど1年が経過したので、この記事ではPages Router と  App Router の違いと、それぞれの利点と適用例を私の所感を交えながら紹介したいと思います。

Next.js は、React ベースのフレームワークとして、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)などの機能を提供しています。バージョン 13 では新しいルーティングシステムである App Router が導入され、従来の Pages Router と比べてより柔軟な機能を備えるようになりました。

Pages Router: シンプルなファイルベースのルーティング

Pages Router は、Next.js が誕生した当初から提供されているルーティングシステムで、pages ディレクトリを使用してルートを定義します。ファイル名がそのまま URL パスに対応し、直感的な構造で利用できる特徴があります。

nextjs.org

主な特徴

  • データ取得の簡便性:
    • getStaticPropsgetServerSideProps を使用して、ページ単位でデータを取得できます。
    • 静的サイト生成(SSG)やサーバーサイドレンダリング(SSR)を簡単に設定可能です。
  • ルートごとのコード分割:
    • 各ページは独立した JavaScript バンドルとしてロードされるため、初期ロードが速くなります。
  • ファイルシステムベースのルーティング:
    • pages ディレクトリ内のファイルが自動的にルートとして設定されます。
    • 例: pages/about.js/about に対応します。

利点
  • シンプルで直感的:
    • ルート設定がファイルシステムベースで行われるため、ディレクトリ構造を見ればサイトの全体像が把握しやすいです。
  • 学習コストが低い:
    • App Routerと比較して、学習コストが低く、React の基本知識と Next.js 固有のルールを少し学べば、すぐに使い始められます。
欠点
  • レイアウトの管理が複雑:
    • 複数のページにまたがる共通レイアウトの管理が煩雑になることがあります。
  • 大規模アプリケーションでのスケーラビリティの問題:
    • 大規模アプリの開発等でページ数が増えると、pages ディレクトリの管理が難しくなることがあります。

 

Pages Router を使うべき場面の具体例

  • シンプルな企業サイトやランディングページ:
    • 企業のコーポレートサイトやプロダクトのランディングページなど、ページ数が少なく、静的なコンテンツが主な場合に最適です。シンプルなファイル構成で開発がしやすく、SSG を利用することで高速なページ読み込みを実現できます。
  • 個人ブログや小規模なブログサイト:
    • getStaticProps を使用して、ビルド時に記事データを取得することで、静的に生成された高速なブログサイトを構築できます。ルーティングも直感的で、記事のページ数が増えても管理が容易です。
  • API ベースのヘッドレス CMS サイト:
    • Contentful や Strapi などのヘッドレス CMS からデータを取得し、静的に生成するようなサイトでは、Pages Router を利用することで簡単に SSG と SSR を切り替えながら開発できます。

 

 

App Router: 次世代の柔軟なルーティング

Next.js 13 で導入された App Router は、app ディレクトリを使用してルーティングを行います。この新しいルーティングシステムは、従来の Pages Router よりもモジュール化されており、React Server Components などの最新の機能をサポートしています。

nextjs.org

主な特徴

  • React Server Components のサポート:
    • サーバーコンポーネントとクライアントコンポーネントを使い分けることで、パフォーマンスを最適化できます。
  • 柔軟なレイアウト管理:
    • layout.js ファイルを使用して、ネストされたルートごとにレイアウトを定義できます。
    • 共通レイアウトやネストされたレイアウトを簡単に構成可能です。
  • 新しいデータ取得の方法:
    • getStaticPropsgetServerSideProps の代わりに、use フックや React の標準 API を使用してデータを取得します。
    • コンポーネント単位でデータフェッチのタイミングを柔軟に制御可能です。
  • ディレクトリベースのルーティング:
    • app ディレクトリを使用してルーティングを行います。
    • 例: app/about/page.js/about に対応しています。

利点
  • 高い柔軟性とモジュール化:
    • レイアウトやデータ取得の管理がしやすく、再利用性が高いです。
  • パフォーマンスの向上:
    • サーバーコンポーネントを使用することで、初期ロードの時間を短縮し、ユーザーにとっての体感速度が向上します。
  • 階層化されたルーティング:
    • ネストされたルートとレイアウトの管理が簡単で、複雑なアプリケーション構造に対応しやすいです。
欠点
  • 学習コストが高い:
    • サーバーコンポーネントや新しいデータ取得の仕組みを理解する必要があり、従来の Pages Router よりも学習コストが高いです。
  • 互換性のないライブラリがある:
    • 一部のライブラリやツールは、従来のPages Routerに依存している可能性があり、App Routerとの互換性が保証されていない場合があります。

 

App Router を使うべき場面の具体例

  • 大規模な Web アプリケーション:
    • ダッシュボードや管理画面、EC サイトなど、複雑な画面構成と大量のデータを扱うアプリケーションに最適です。サーバーコンポーネントを活用し、データフェッチをサーバー側で処理することで、クライアントの負荷を軽減し、パフォーマンスを向上させられます。
  • 動的なデータが多いアプリケーション:
    • ユーザーごとに異なるデータを表示するようなアプリケーション(例えば、ユーザーごとの設定ページやダッシュボードなど)では、サーバーサイドでのデータ取得が柔軟に行える App Router が適しています。サーバーコンポーネントとクライアントコンポーネントを組み合わせることで、データ取得と表示を最適化できます。
  • 多階層のレイアウトが必要なアプリケーション:
    • 複数のレイアウトがネストされているアプリケーション、例えばマルチテナント型のアプリケーションや、管理画面とユーザー向け画面で異なるレイアウトを持つ場合、App Router の柔軟なレイアウト管理機能を活用することで、開発が容易になります。
  • SSR と CSR の柔軟な切り替えが必要なアプリケーション:
    • 一部のコンポーネントは SSR でレンダリングし、他の部分はクライアントサイドでインタラクティブに動作させたい場合に、App Router はサーバーコンポーネントとクライアントコンポーネントの混在ができるため、要件に応じて柔軟に切り替えが可能です。

どちらを選ぶべきか?

Pages Router と App Router のどちらを選択するかは、プロジェクトの要件や開発チームのスキルセットに依存します。小規模な場合は「Pages Router」、大規模な場合は「App Router」が適しているのではと感覚的には感じています。

  • 小規模でシンプルなアプリケーション:
    • 学習コストを抑えたい、あるいは素早くプロトタイプを作成したい場合は、Pages Router が適していると考えています。
  • 大規模で複雑なアプリケーション:
    • 高い柔軟性やパフォーマンス、将来的な拡張性を重視する場合は、App Router が適していると考えています。

 

Pages Router 利用者が App Router を使い始めて苦戦したポイント

これまで Pages Router を使用していたところから App Router を利用し始めた際、いくつか考え方の異なる点で戸惑いました。

  • サーバーコンポーネントとクライアントコンポーネントの違い:
    • App Router では、サーバーコンポーネントとクライアントコンポーネントを使い分ける必要があります。
      これにより、クライアント側でしか使用できないフック(例: useStateuseEffect)が使えなくなるため、どのコンポーネントをどこで使用するかを十分に理解したうえで設計する必要があります。
      この違いを理解し、使い分けることがあったため、苦戦しました。
  • レイアウトの階層管理の複雑さ:
    • App Router では、layout.js を用いてレイアウトを管理しますが、これによりルートごとのレイアウトの階層構造を理解し、管理する必要があります。
      ネストされたレイアウトが多くなると、どのページがどのレイアウトを使用しているのかを把握するのが難しくなりがちです。特に Pages Router のシンプルな構造に慣れていると、最初は煩雑に感じました。
      しかし、慣れてくるとレイアウトのネストができるため、特定のページやページのグループごとに異なるレイアウトを適用することが容易で便利と感じるようになってきました。
  • データフェッチの方法の変化:
    • getStaticPropsgetServerSideProps の代わりに、React の use フックや標準 API を使ったデータフェッチに慣れる必要があります。
      特に、サーバーコンポーネントでのデータフェッチとクライアントコンポーネントでのデータフェッチの使い分けが難しく、どのタイミングでデータが取得されるかを理解するのに苦労しました。
  • App Router 固有のファイル構成の理解:
    • App Router では、page.jslayout.jsloading.jserror.js など、特定の役割を持つファイルを使い分ける必要があります。
      これにより、各ファイルの役割を理解し、正しい場所に配置する必要があります。このファイル構成に慣れていなかったため、初めての設定時にどこに何を置くべきか迷いました。
      慣れてくると、エラーハンドリング時のページ遷移などが容易となり、開発のしやすさに繋がっています。

 

まとめ

Next.js 13 で導入された App Router は、従来の Pages Router に比べて多くのメリットがありますが、使いこなすには学習コストが必要と感じています。Next.js の公式では App Router の使用が推奨されていますが、各プロジェクトの要件に応じて、どちらのルーティングシステムを採用するかを慎重に検討することが重要と考えています。

執筆者:小畑美幸

現在はフロントをメインに開発しているエンジニア。
ただただPerfumeが好きです。