Reactのキャッチアップをしたので、今度はNext.jsを学んでみる
ご挨拶
皆さん、こんにちは
先日、
dtm3110.hatenablog.com
こちらのブログを投稿しました。
今回はその続きでNext.jsに関してキャッチアップしてみましたので、前回と同様にまとめてみようと思います。
そもそもなんでキャッチアップしたのん?
この質問に関しては、前回のブログと同様に近日中にこちらのブログでご紹介しようと思います!!
乞うご期待!!!
キャッチアップ内容
キャッチアップし始める際、いつもどおり、Next.jsのチュートリアルである「 Create a Next.js App | Learn Next.js 」を実施しました。
基本的にはこのチュートリアルのみを実施しましたが、とても良くNext.jsの機能や使い方がまとめてありましたので、Next.jsを学習する方はぜひぜひしっかりこのチュートリアル見て、触ってみてください。
今回はNext.jsの中でも、一番の山場になりそうな「Data Fetching」の機能を中心に下記のような機能をそれぞれご紹介します。
# | カテゴリ | 対象(略称) |
---|---|---|
1 | Data Fetching | Static Generation (SSG) |
2 | Data Fetching | Server-side Rendering (SSR) |
3 | Data Fetching | Single Page Application (SPA) |
4 | Data Fetching | それぞれの特性まとめ |
5 | routing | Next.jsの基本的なディレクトリ構成と役割 |
6 | API | Next.jsのAPI |
1. Static Generation (SSG)
下の表にある通り、Build時にClientユーザーがアクセスするファーストビューのHTMLを生成しておく処理手法。
Clientユーザーがアクセスした際、外部データへの接続(API Call & データ取得)などの処理や、そのデータを用いたHTMLファイルの生成といった処理をせずに、そのまま生成済みのHTMLファイルを取得するため、「ファーストビューを表示する」という観点では、以降に説明する2つの方式より圧倒的に早い。
一方、Build時にデータごとHTMLファイルを作成するという仕様上、リアルタイムデータを用いるようなWebページを表示するのには適していない。
もし仮にリアルタイムデータを使いながらSSGでレンダリングする場合は、固定データのみSSRでBuildさせ、HTMLファイルを読み込み後にClient-side(SPA)側からAPIをコールして生成するような形になる。
Key | Contents |
---|---|
正式名称 | Static Generation |
イメージ | |
概要 | Build時にファイルを生成する方式。ファーストビューがとても早い。 |
データ読込関数 | 一括取得: getStaticProps 動的ページでの取得: getStaticPaths |
メリット | Build時にHTMLを生成し、クライアント側からアクセスされた際にすぐにそのHTMLを返すことにより、ファーストビューを高速に表示する事ができる |
デメリット | 頻繁なデータ更新があるサイト(Twitter等のSNSや) |
ユースケース | データの更新が頻繁ではないが、ファーストView内にデータ量が多いwebページを表示する場合(データサマリー画面など) |
補足(getStaticProps
とgetStaticPaths
の違いと使い分け)
getStaticProps | getStaticPaths | |
---|---|---|
利用条件 | ページ内のコンテンツに 外部データを含む |
ページのパス自体に 外部データを含む |
利用パターン | 全体サマリー画面などとして利用されることが多い。 | 詳細画面などとして利用されることが多い。 |
備考 | コンテンツ内のデータを取得。単体でも使えるが、idを引数として持ってgetStaticPaths で取得したキーから該当のデータを参照したりもする |
「getStaticPaths で対象のIDなどのキーを取得し、getStaticProps でそのキーを受け取って、該当のデータを表示」といったあわせ技が中心 |
例 |
2. Server-side Rendering
Clientユーザーがアクセスした際に、サーバ側でAPIのCall等をしてデータを取得し、表示用のHTMLファイルを返す処理手法。
Backend for Frontend(BFF)の思想が、「Client側のCallに対してFrontendで必要なデータ等を取得・整形して返すBackend」ということから、SSRはBFFの一種と言っても良い(ClientユーザーのCallに対して整形済みのHTMLを返すため)。
こちらの手法では、サーバ側で必要なデータのAPI Callを実施するため、Clientの利用しているデバイスや通信環境等による影響を受けない。
またSPAと違い、各種APIのレスポンスに含まれる不要データを一次取得するといったこともせず、サーバ側で整形され生成されたHTMLを取得するので、Clientユーザーのデータ通信量的にも優しい。
Key | Contents |
---|---|
正式名称 | Server-Side Rendering |
イメージ | |
概要 | Clientからのアクセス時にHTMLを生成する方式。役割上、BFF(Backend for Fronend)としてフロントエンドのためにHTMLファイルを生成してClientに返している。 |
データ読込関数 | getServerSideProps のみ |
メリット | HTMLを生成するのはNext.jsのServer側なので、閲覧する端末の処理速度に依存せずに画面を生成することこができる。Server上でAPIとの疎通もあるので、クライアント側からコールするより処理速度は早くなる(ハズ) |
デメリット | アクセスしたあとにHTMLを生成するので、ファーストビューはどうしてもSSGより遅くなる |
ユースケース | データの更新が頻繁に行われており、複数のデータソースへのアクセス(API)を利用している |
3. Single Page Application
一つのHTMLファイルを受け取り、Clientユーザーのデバイス上のJavaScriptから各種データを取得し、そのデータをもとにHTML内にデータ表示することで画面を表示する手法。
画面遷移をなくすことで、サーバーとの疎通を最小限にし、Clientユーザー側ではアクションに応じたデータ取得だけをすることで、ブラウザに依存しないユーザー体験を提供することができる。
Key | Contents |
---|---|
正式名称 | Single Page Application Next.jsでは Client-side Rendering |
イメージ | |
概要 | クライアントユーザーがリクエストした際、空のHTMLを返し、JavascriptによるAPIのCallで各種データを取得、Viewを表示する方法。 |
データ読込関数 | 各種APIをクライアント側でCallして取得 |
メリット | 画面遷移がないため、ブラウザ自体の挙動に依存せず、高度なWeb表現(ユーザーアクションがなされた場所だけデータを更新など)が可能 |
デメリット | クライアント側でデータをそれぞれ取得しに行くため、ファーストビューは致命的に遅い。 クライアント側のデバイスによって通信速度の差が現れ、APIのレスポンスすべてをクライアント側で処理するため、BFFなどが間にない場合はデータの通信量が肥大化する |
ユースケース | SNSの新規メッセージ表示などのリアルタイムデータの表示 |
4. それぞれの特性まとめ
- 略図説明
- SPA
- SSR
- SSG
- First View描画時間
- リアルタイムデータの扱い
使い分けの仕方
First Viewを最速で表示することは、UX的にもSEO的にも重要です。伴ってSSGはとても強力な手法と言えます。
一方、リアルタイムに変動するデータ(SNSや株情報など)や、HTMLを取得した後に判定するもの(Auth情報)がある場合はSSG(もしくはSPA)を利用する必要があります。
結論、各ページにたいして、そのページで利用されるデータがどのタイミングでどのように利用されるデータなのか考えながら、適切な手法を適応していくことが重要です。
4. Next.jsの基本的なディレクトリ構成と役割
ディレクトリ構成は各プロジェクトに任されている部分が多いですが、その中でもだいぶポピュラーな部分を抜粋して紹介します。
root/ ┠ pages/ ┃ ┠ _app.js(.tsx) ┃ ┠ _document.js(.tsx) ┃ ┠ api/ ┃ ┃ ┗ hogehoge/ ┃ ┃ ︙ ┃ ┃ ┗ index.js(.tsx) ┃ ┠ hogehoge/ ┃ ┃ ︙ ┃ ┃ ┗ index.js(.tsx) ┃ ┠ 404.js(.tsx) ┃ ┗ index.js(.tsx) ┠ components ┃ ┠ 〇〇.module.css ┃ ┗ 〇〇.js(.tsx) ┗ public/
名称 | Type | 説明 |
---|---|---|
pages | Directory | 外部からアクセスできる(Routing)されるファイルを格納するDirectory このDirectory内の階層がRoutingのpathになる |
_app.js(.tsx) | File | 全ページに関わる初期化処理を指定する 例)
|
_document.js(.tsx) | File | 全ページに関わる初期化処理を指定する。中でも、HTMLのメタタグやHTMLの大本の構成を定義する。 _app.js(tsx)と異なり、こちらはSSRでのみ実行されるため、Client側の処理を記述はしないように注意 例)
|
api | Directory | APIの処理部を記載するDirectory 階層構造がそのままAPIのエンドポイントになる Dynamic API Routeの場合はhandlerにqueryを記載し、それに合わせたファイル名( /api/posts/[postId].js 等)を指定する必要がある詳しくはこちら |
404.js(.tsx) | File | Routingで一致しなかった場合に出力される画面の記述 |
pages/index.js(.tsx) | File | ホーム画面を記述するファイル |
components | Directory | コンポーネントとして分離したファイルを格納するDirectory 用途によってどのように下位Directoryを設計するかがポイント スタイルなどもここにまとめる事が多い |
〇〇.module.css | File | CSSモジュールを利用する場合はファイル名をこの形式にする必要がある |
public | Directory | 主にfaviconや、画像ファイルなどのメディアを格納するDirectory |
5. Next.jsのAPI
next/link
- クライアント側のナビゲーション
- SPAの画面遷移
- デフォルトで遷移先画面のプリフェッチをするため、描画が早い
next/head
- HTMLのヘッダー内のメタデータとかを設定できる
- お作法として、タグが重複Renderingしないようにkeyプロパティを入れる
- 格納するメタタグたちは、Headの直下に置く必要がある
next/router
- routerObjectを使うには
useRouter
を呼び出す必要がある - Reactフックでつかうため、クラスでは使えない
- router.prefetchという、プリフェッチ機能がある(
next/link
ではデフォルトでプリフェッチするので、next/routerでは
明示的に利用する必要がある)- 使用例:ログインページ →(ここでprefetch使う)→ Dashboardにリダイレクト
- routerObjectを使うには
next/document
_document.js(.tsx)
で使う、HTML拡張用のAPI
最後に
チュートリアル最初の「Create a Next.js App」を軽く目を通して見て、Vue.jsを主に使って開発していた感覚からすると、
Next.jsは大枠でみると、「Vue-cilの役割とVue-routerの役割を担っているReactのフレームワーク」という認識でした。
一方で、First-Viewを早くするためのData Featching周りの機能や、コードの分割機能等のよりユーザビリティを考えたUXを構築するための機能が結構充実しているということがわかりました。
今後は最適なDataFetching方法を考えたりしながら、実際にアプリを作ることで実際の使い方を身に着けていく予定です。