Open17

Learn Next.jsを読む

harapekoharapeko

モチベ

これまで、なんとなくで触ってきてしまったので学習資料をいまさら読む

※知っていることは残さない
※振り返ってまた見そうなものは残す

https://nextjs.org/

harapekoharapeko

1.新規プロジェクト作成

https://nextjs.org/learn/dashboard-app/getting-started

指示に従って作成し、ディレクトリ構造を確認し、実行する

  • /app:アプリ全体のルートやロジックを管理するフォルダ
  • /app/lib:再利用可能な関数やデータ取得用の関数を集めたフォルダ
    • app/lib/placeholder-data.ts:プレースホルダーデータ。DB設定時に投入する
    • /app/lib/definitions.ts:データ形式が定義され誤った形式を渡さないためのミス防止になる
  • /app/ui:カードやテーブルなど、事前にスタイルされたUIコンポーネント用のフォルダ
  • /public:画像などの静的ファイルを保存するフォルダ
  • 設定ファイル:プロジェクト作成時に自動生成される設定ファイル(今回は変更しない)

確認したら開発サーバを起動する
画面が見えたらOK

harapekoharapeko

2.CSSスタイル

  • /app/ui/global.css:CSSリセット、HTML要素などのサイト全体のスタイルを追加できる(として扱う)
    • 通常、トップレベルのコンポーネントで読み込んで使う。任意コンポーネントではなく
    • ここでは、/app/layout.tsxで読み込む。スタイル反映が確認できる
  • global.css、/app/page.tsxを見るとtailwindを使用していることが分かる
  • CSSモジュールは、一意のクラス名で作成、コンポーネントに適用するので、スタイル衝突の心配がない
  • clsxライブラリでクラス名を簡単に切り替えられる(例:.pending、.paid)
  • 他の方法
    • Sassによる.css、.scssファイル読み込み
    • CSS-in-JS
harapekoharapeko

3.フォントと画像の最適化

フォント

  • next/fontモジュールはビルド時にフォントをDL、静的アセットとともにホスティングします。追加のネットワーク要求が発生しません
  • next/font/googleからInterモジュールをインポートし、サブセットを指定、bodyにInterを追加すると、アプリケーション全体にフォントが適用される
  • Tailwindのantialiasedがあるとフォントを滑らかになる
  • 開発者ツールでbodyのスタイルを確認するとInter、INter_Fallbackが適用されていることが確認できる
  • 複数のフォントを読み込むことや、フォントウェイトの指定も可能

画像

  • /publicに静的アセットを提供できる
  • Imageコンポーネントによる最適化
    • レイアウトシフト防止(サイズを書いてくれるのかな
    • 適切なビューポートでの画像サイズ変更
    • 遅延読み込み
    • WebP、AVIFでの画像提供
harapekoharapeko

4.レイアウトとページの作成

  • ファイルシステムルーティング
  • Partialレンダリング:ナビゲーション時にページコンポーネントのみが更新され、レイアウトは再レンダリングされない
  • /app/layout.tsxルートレイアウト:すべてのページで使用できる共有レイアウトを作成する
harapekoharapeko

5.ページ間の移動

  • Linkコンポーネントを使用して、ページ間をリンクできる
    • JSでクライアントサイドナビゲーションを行う
    • 一部はサーバー上でレンダリングされ、全体更新はされないのでWebアプリのように感じられる

自動コード分割とプリフェッチ

  • ルートセグメントごとにアプリケーションを自動的にコード分割する
    • これは従来のReact APSとは異なる
    • 初期読み込み時にすべてのアプリケーションコードを読み込む
  • 本番環境では、Linkコンポーネントがビューポートに表示されるたびに、リンクされたコードをバッググラウンドで自動的にプリフェッチする

アクティブなリンクを表示する

  • 現在リンクの表示はusePathname()でパス確認を行う実装に使用できる
harapekoharapeko

6.DB設定

指示通りに進めていけばよいが、一部ちゃんと読まないと挫折しそうな人が出そうな部分があった

書いてある通りだが、すべてのコメントを外し、この部分をコメントしないとデータ投入処理が到達不可

/app/seed/route.ts
export async function GET() {
-  return Response.json({
-    message:
-      'Uncomment this file and remove this line. You can delete this file when you are finished.',
-  });
略
}
harapekoharapeko

7.データの取得

  • APIレイヤー:アプリケーションコードとDB間の中間層
  • データベースクエリ:DBとやりとりするためのロジックを記述する
    • RSCを使用している場合は、APIレイヤーをスキップして、DBの秘密をクライアントに公開するリスクなしに、DBを直接クエリできる

サーバーコンポーネントを使用してデータを取得する

  • RSCはPromiseサポート
  • async/awaitで非同期にデータ取得可能(データ取得ライブラリuseEffect、useStateを使わず)
  • コストのかかるデータ取得、ロジックをサーバー上に保持し、結果のみをクライアントに送信可能
  • サーバ上で実行されるため、追加のAPIレイヤーなしでDBに直接クエリ可能

注意点

  1. データ要求が意図せず相互にブロックされ、要求ウォーターフォールが発生する
  2. デフォではパフォーマンス向上でルートを事前レンダリングする
    • これは静的レンダリングと呼ばれる。そのため、データが変更されてもダッシュボードには反映されない

この章では、1番について取り扱い、次章で2番について説明する

リクエストウォーターフォールとはなにか

  • 前のリクエスト完了に依存する一連のネットワークリクエストを指す
  • データ取得の場合、各リクエストは前のリクエストがデータを返した後にのみ開始できる
  • 例:fetchLatestInvoices()前に、fetchRevenue()を待つ必要がある
    • 次のリクエストを行う前に条件を満たす必要がある

並列データ取得

  • 並行して要求すればウォーターフォールは回避できる
  • Promise.all()、Promise.allSettled()を利用
  • パフォーマンスが向上する
  • しかし、1つのデータ要求が他のすべての要求よりも遅い場合はどうなるか?
harapekoharapeko

8.静的および動的レンダリング

静的レンダリング

  • ビルド時・デプロイ時またはデータ再検証時にサーバ上で行われる
  • アクセスのたびキャッシュ結果が提供される
  • 利点
    • 高速、エッジCDN
    • 負荷軽減
    • SEO:ページ読み込み時にコンテンツが利用可能なためクローラーがインデックスを作成しやすい
  • 静的なブログ投稿、製品ページ、データのないUI、ユーザ間で共有されるデータには便利
  • 不向き
    • 定期的に更新されるパーソナライズされたデータを持つダッシュボード

動的レンダリング

  • アクセス時にコンテンツがサーバ上でレンダリングされる
  • 利点
    • リアルタイムデータ
    • ユーザ固有コンテンツ
    • リクエスト時の情報:Cookie、URL検索パラメータなど、リクエスト時のみ知ることができる情報にアクセスできる