Open17
Learn Next.jsを読む
モチベ
これまで、なんとなくで触ってきてしまったので学習資料をいまさら読む
※知っていることは残さない
※振り返ってまた見そうなものは残す
1.新規プロジェクト作成
指示に従って作成し、ディレクトリ構造を確認し、実行する
- /app:アプリ全体のルートやロジックを管理するフォルダ
- /app/lib:再利用可能な関数やデータ取得用の関数を集めたフォルダ
- app/lib/placeholder-data.ts:プレースホルダーデータ。DB設定時に投入する
- /app/lib/definitions.ts:データ形式が定義され誤った形式を渡さないためのミス防止になる
- /app/ui:カードやテーブルなど、事前にスタイルされたUIコンポーネント用のフォルダ
- /public:画像などの静的ファイルを保存するフォルダ
- 設定ファイル:プロジェクト作成時に自動生成される設定ファイル(今回は変更しない)
確認したら開発サーバを起動する
画面が見えたらOK
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
3.フォントと画像の最適化
フォント
- next/fontモジュールはビルド時にフォントをDL、静的アセットとともにホスティングします。追加のネットワーク要求が発生しません
- next/font/googleからInterモジュールをインポートし、サブセットを指定、bodyにInterを追加すると、アプリケーション全体にフォントが適用される
- Tailwindのantialiasedがあるとフォントを滑らかになる
- 開発者ツールでbodyのスタイルを確認するとInter、INter_Fallbackが適用されていることが確認できる
- 複数のフォントを読み込むことや、フォントウェイトの指定も可能
画像
- /publicに静的アセットを提供できる
- Imageコンポーネントによる最適化
- レイアウトシフト防止(サイズを書いてくれるのかな
- 適切なビューポートでの画像サイズ変更
- 遅延読み込み
- WebP、AVIFでの画像提供
4.レイアウトとページの作成
- ファイルシステムルーティング
- Partialレンダリング:ナビゲーション時にページコンポーネントのみが更新され、レイアウトは再レンダリングされない
- /app/layout.tsxルートレイアウト:すべてのページで使用できる共有レイアウトを作成する
5.ページ間の移動
- Linkコンポーネントを使用して、ページ間をリンクできる
- JSでクライアントサイドナビゲーションを行う
- 一部はサーバー上でレンダリングされ、全体更新はされないのでWebアプリのように感じられる
自動コード分割とプリフェッチ
- ルートセグメントごとにアプリケーションを自動的にコード分割する
- これは従来のReact APSとは異なる
- 初期読み込み時にすべてのアプリケーションコードを読み込む
- 本番環境では、Linkコンポーネントがビューポートに表示されるたびに、リンクされたコードをバッググラウンドで自動的にプリフェッチする
アクティブなリンクを表示する
- 現在リンクの表示はusePathname()でパス確認を行う実装に使用できる
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.',
- });
略
}
7.データの取得
- APIレイヤー:アプリケーションコードとDB間の中間層
- データベースクエリ:DBとやりとりするためのロジックを記述する
- RSCを使用している場合は、APIレイヤーをスキップして、DBの秘密をクライアントに公開するリスクなしに、DBを直接クエリできる
サーバーコンポーネントを使用してデータを取得する
- RSCはPromiseサポート
- async/awaitで非同期にデータ取得可能(データ取得ライブラリuseEffect、useStateを使わず)
- コストのかかるデータ取得、ロジックをサーバー上に保持し、結果のみをクライアントに送信可能
- サーバ上で実行されるため、追加のAPIレイヤーなしでDBに直接クエリ可能
注意点
- データ要求が意図せず相互にブロックされ、要求ウォーターフォールが発生する
- デフォではパフォーマンス向上でルートを事前レンダリングする
- これは静的レンダリングと呼ばれる。そのため、データが変更されてもダッシュボードには反映されない
この章では、1番について取り扱い、次章で2番について説明する
リクエストウォーターフォールとはなにか
- 前のリクエスト完了に依存する一連のネットワークリクエストを指す
- データ取得の場合、各リクエストは前のリクエストがデータを返した後にのみ開始できる
- 例:fetchLatestInvoices()前に、fetchRevenue()を待つ必要がある
- 次のリクエストを行う前に条件を満たす必要がある
並列データ取得
- 並行して要求すればウォーターフォールは回避できる
- Promise.all()、Promise.allSettled()を利用
- パフォーマンスが向上する
- しかし、1つのデータ要求が他のすべての要求よりも遅い場合はどうなるか?
8.静的および動的レンダリング
静的レンダリング
- ビルド時・デプロイ時またはデータ再検証時にサーバ上で行われる
- アクセスのたびキャッシュ結果が提供される
- 利点
- 高速、エッジCDN
- 負荷軽減
- SEO:ページ読み込み時にコンテンツが利用可能なためクローラーがインデックスを作成しやすい
- 静的なブログ投稿、製品ページ、データのないUI、ユーザ間で共有されるデータには便利
- 不向き
- 定期的に更新されるパーソナライズされたデータを持つダッシュボード
動的レンダリング
- アクセス時にコンテンツがサーバ上でレンダリングされる
- 利点
- リアルタイムデータ
- ユーザ固有コンテンツ
- リクエスト時の情報:Cookie、URL検索パラメータなど、リクエスト時のみ知ることができる情報にアクセスできる