Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Next.js

Recruit
August 10, 2023

 Next.js

2023年度リクルート エンジニアコース新人研修の講義資料です

Recruit

August 10, 2023
Tweet

More Decks by Recruit

Other Decks in Technology

Transcript

  1. Time Table ▪【第1章】フロントエンド開発と SPA フレームワーク(15m) ▪【第2章】Next.js の SPA(30m) ▪【第3章】Next.js の

    BFF(60m)  → 昼休憩(12:00 〜 13:00) ▪【第4章】 Next.js と パフォーマンス(90m) ▪【第5章】Next.js と ライブラリ(60m)  → 休憩(15:30 〜 16:00) ▪【第6章】簡単なアプリを作ってみよう( 120m) ✏ 研修用 GitHub リポジトリのクローンをお願いします https://github.com/recruit-tech/bootcamp-2023-nextjs
  2. Time Table ▪【第1章】フロントエンド開発と SPA フレームワーク(15m) ▪【第2章】Next.js の SPA(30m)📌:2-x ▪【第3章】Next.js の

    BFF(60m)📌:3-x  → 昼休憩(12:00 〜 13:00) ▪【第4章】 Next.js と パフォーマンス(90m)📌:4-x ▪【第5章】Next.js と ライブラリ(60m)📌:5-x  → 休憩(15:30 〜 16:00) ▪【第6章】簡単なアプリを作ってみよう( 120m)📌:5-x スライドの解説中(📌:2-x)の様にサンプルコードの箇所を参照することがあります https://github.com/recruit-tech/bootcamp-2023-nextjs
  3. Time Table ▪【第1章】フロントエンド開発と SPA フレームワーク(15m) ▪【第2章】Next.js の SPA(30m)📌:2-x ▪【第3章】Next.js の

    BFF(60m)📌:3-x  → 昼休憩(12:00 〜 13:00) ▪【第4章】 Next.js と パフォーマンス(90m)📌:4-x ▪【第5章】Next.js と ライブラリ(60m)📌:5-x  → 休憩(15:30 〜 16:00) ▪【第6章】簡単なアプリを作ってみよう( 120m)📌:5-x 解説中、迷子になった場合( 📌)で検索して該当コードを見つけてください https://github.com/recruit-tech/bootcamp-2023-nextjs
  4. 開発環境の確認 ▪ 最新の Node.js(18.16.0 LTS) ▪ Docker Desktop ▪ リポジトリをクローンしたら、

    node_moduels をインストールしておきましょう  → $ npm i 上記の開発環境が整っていることを前提に、研修を進めます
  5. 第1章 フロントエンド開発と SPA フレームワーク JSX(TSX)は、 UI コンポーネント(View)を関数で実装します ▪ 入力(Props)を与えると、出力(HTML)を得る ▪ 要素一覧、ボタン、フォームなど

    ▪ 小さい UI コンポーネントを組み上げる  → ページ相当の UI コンポーネントが出来る  → 先日の React 研修のとおり UI コンポーネント単位の開発
  6. 第1章 フロントエンド開発と SPA フレームワーク React は UI ライブラリ ▪ UI コンポーネント実装・レンダリングに特化

    ▪ ページとして提供する方法は、別途必要になる  → Web アプリケーションサーバーとしての機能は持たない UI コンポーネント単位の開発
  7. 第1章 フロントエンド開発と SPA フレームワーク MPA はリクエストごとに HTML を表示 ▪ MPA は

    SPA との対比で使用される用語  → Multi Page Application / Single Page Application ▪ 複数 の HTML ページで構成される  → サーバーが HTML をレスポンス  → 状態の復元は Cookie などを頼りに SPA・MPA の違い 画面遷移毎に「ページのリクエスト」が発生するもの HTML 画面遷移 HTML HTML 画面遷移
  8. 第1章 フロントエンド開発と SPA フレームワーク SPA は DOM を適宜書き換えることで、画面遷移 ▪ 初回レスポンスは、単一 HTML

    ▪ URL 変更(History API)に応じて JSON を非同期で取得 ▪ JSON を HTML コンテンツとして書き換え  → 仮想 DOM を更新・実 DOM に反映  → ブラウザ上で動的に HTML に反映 SPA・MPA の違い 画面遷移毎に「コンテンツの書き換え」が発生するもの HTML 画面遷移 画面遷移 JSON JSON
  9. 第1章 フロントエンド開発と SPA フレームワーク ✅ SPA/MPA の違いは「画面遷移」である ▪ SPA は画面遷移しても、ブラウザの状態が破棄されない  → 一度取得したデータ、ユーザーの状態を維持できる

    ▪ 非同期で必要なコンテンツのみをダウンロードする  → データソースアクセスが必要最小限に  → 画面遷移が高速 SPA・MPA の違い HTML 画面遷移 画面遷移 JSON JSON React は SPA のためとは限らない
  10. 第1章 フロントエンド開発と SPA フレームワーク 単一の HTML で SPA 展開するもの ▪ 典型的な

    SPA(古典的な SPA) ▪ 初期描画では不要な JavaScript バンドルのロードが発生  → FID ※1 の低下に直結 ▪ 最適化にはチューニングが必要 フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 初回ロードで大量の JavaScript バンドルファイルを取得する必要 大量のJavaScript 課題 ※1 FID(First Input Delay)コアウェブバイタルの指標の 1つ。初回入力までの遅延時間。
  11. 第1章 フロントエンド開発と SPA フレームワーク React 公式がフレームワーク使用を推奨 ※1 している ▪ 新しいアプリを作る場合になぜ推奨されるのか?  → アプリの肥大化に応じて

    FID が遅くなりがち(バンドルサイズの肥大化)  → データ取得のニーズが多様化(データ取得の然るべきタイミングと頻度)  → React に限らず、他フロントエンド実装でも同様のチューニングが必要 フレームワークを採用する利点 主にパフォーマンス観点で、フレームワークが欠かせなくなっている ※1 Can I use React without a framework? :https://react.dev/learn/start-a-new-react-project#can-i-use-react-without-a-framework
  12. 第1章 フロントエンド開発と SPA フレームワーク 複数の HTML で SPA 展開するもの ▪ Next.js、Remix、Sveltekit、Nuxt、...etc

    ▪ バンドラーを含み、ページ毎のレスポンス(ダウンロードファイル)が最適化 ▪ ページによって、動的・静的にレスポンスを選択する フレームワークを採用する利点 HTML 画面遷移 画面遷移 JSON JSON 具体的にどのようなアプローチが採用されるのか、1日の研修を通して解説します SPA フレームワーク 解決 ?
  13. 第2章 Next.js の SPA create next app を実行してみよう ▪ create next

    app とは?  → Next.js プロジェクトの雛形生成ツール ▪ $ npx create-next-app@latest 【実技】Next.js プロジェクトを作ってみよう (消す前提なので)まずは適当なディレクトリで試してみましょう
  14. 第2章 Next.js の SPA # プロジェクト名称は? ✔ What is your project

    named? … my-app # TypeScript 使う? ✔ Would you like to use TypeScript with this project? … No / Yes # ESLint(コーディング規約)使う? ✔ Would you like to use ESLint with this project? … No / Yes # Tailwind CSS(CSS フレームワーク)使う? ✔ Would you like to use Tailwind CSS with this project? … No / Yes # 「src」ディレクトリ使う? ✔ Would you like to use `src/` directory with this project? … No / Yes # 「app」ディレクトリ使う? ✔ Would you like to use experimental `app/` directory with this project? … No / Yes # import エイリアスは? ? What import alias would you like configured? › @/* 【実技】Next.js プロジェクトを作ってみよう
  15. 第2章 Next.js の SPA Next.js 開発サーバーを起動してみよう ▪ $ cd my-app ▪

    $ npm run dev ▪ http://localhost:3000/ を確認してみよう ▪ 「Ctrl + C」で開発サーバーを終了 【実技】Next.js プロジェクトを作ってみよう ✅ Next.js プロジェクトの準備はこれで完了!
  16. 第2章 Next.js の SPA 研修リポジトリの「packages/chapter-2」を使用します ▪ カレントディレクトリを移動して  → $ cd packages/chapter-2 ▪

    開発サーバーを起動して  → $ npm run dev 【実技】pages ルーティングを体験してみよう 研修リポジトリのサンプルは、 create next app で作成しました
  17. 第2章 Next.js の SPA ファイルシステムベースのルーティング ▪ フォルダ構成と命名規則で、ルーティングが決まる packages/chapter-2/src/pages ├── about.tsx ├──

    blog │ └── [slug].tsx └── index.tsx 【実技】pages ルーティングを体験してみよう ← http://localhost:3000/about ← http://localhost:3000/blog/{slug} ← http://localhost:3000
  18. 第2章 Next.js の SPA ファイルシステムベースのルーティング ▪ 「pages」 というディレクトリに「 Page ファイル」を配備する  → pages

    ディレクトリに配備するだけで、ルーティング対象となる  → ページ相当の UI コンポーネントを export default(📌:2-1) 【実技】pages ルーティングを体験してみよう
  19. 第2章 Next.js の SPA Link コンポーネントを使用した SPA ナビゲーション ▪ import Link

    from "next/link";  → a要素のように使用。href 属性を指定する(📌:2-2) 【実技】pages ルーティングを体験してみよう
  20. 第2章 Next.js の SPA Router を使用した SPA ナビゲーション・参照 ▪ import {

    useRouter } from "next/router";  → router.push を使用すると、SPA ナビゲーションできる( 📌:2-3)  → router.query を参照すると、path パラメーターが参照できる( 📌:2-4)  → router.query を参照すると、query パラメーターが参照できる( 📌:2-5) 【実技】pages ルーティングを体験してみよう
  21. 第2章 Next.js の SPA ファイルシステムの命名規則と、 Router の使い方が基本 ▪ Link コンポーネントや Router

    を使用すると、SPA ナビゲーションができる ▪ ページルーティングは、ファイルを配置するだけ ▪ 命名規則によってリクエストパラメーターを取得できる ✅ 単純な SPA サイトなら、すぐに実装できる
  22. 第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動  → ▪

    Next.js アプリ(本番サーバー)のビルド  → ▪ Next.js アプリ(本番サーバー)の起動  → 【実技】npm script を試してみよう
  23. 第2章 Next.js の SPA 開発サーバー・本番サーバーは別物 ▪ Next.js アプリ 開発サーバーの起動  → $ npm

    run dev ▪ Next.js アプリ(本番サーバー)のビルド  → $ npm run build ▪ Next.js アプリ(本番サーバー)の起動  → $ npm start 【実技】npm script を試してみよう 研修後半、使い分けるため注意
  24. 第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =

    0; を適当に追加 ▪ $ npm run build  → 【実技】npm script を試してみよう
  25. 第2章 Next.js の SPA TypeScript の型互換エラーがある状況でビルドしてみよう ▪ const value: string =

    0; を適当に追加 ▪ $ npm run build  → Type error: Type 'number' is not assignable to type 'string'. 【実技】npm script を試してみよう 型互換エラーがあるとビルドに失敗する
  26. ESLint コーディング規約違反がある状況でビルドしてみよう ▪ (📌:2-6)の行を削除 ▪ $ npm run build  → 

    ▪ $ npm run lint eslint の実行(コーディング規約違反チェック)  →  第2章 Next.js の SPA 【実技】npm script を試してみよう
  27. ESLint コーディング規約違反がある状況でビルドしてみよう ▪ (📌:2-6)の行を削除 ▪ $ npm run build  → Type

    error: Property 'alt' is missing in type ▪ $ npm run lint eslint の実行(コーディング規約違反チェック)  → Warning: Image elements must have an alt prop 第2章 Next.js の SPA 【実技】npm script を試してみよう ESLint コーディング規約違反があるとビルドに失敗する
  28. 第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ SSR(Server Side Rendering)機能  → データ取得

     → リクエスト単位の検証(認証認可)  → 正常系以外のレスポンス(リダイレクト、エラー表示) Next.js の BFF とは SSR は SEO 観点でも必要になることがある
  29. 第3章 Next.js の BFF Web アプリケーションサーバーとしての機能 ▪ Web API 機能  → データ取得・更新

     → リクエスト単位の検証(認証認可)  → クレデンシャル情報を扱う外部連携 Next.js の BFF とは 静的サイトとの大きな違い
  30. 第3章 Next.js の BFF 外部サーバー(サブシステム)との中継役を担い、永続層と接続する ▪ VPC ネットワーク内の外部サーバー(サブシステム)と疎通  → バックエンド API サーバーと疎通

     → API サーバーから取得したデータの集約(アグリゲーション) ▪ DB サーバーと疎通  → Prisma など ORM 経由で Next.js の BFF とは システム構成によって使い分けることができる
  31. 第3章 Next.js の BFF 基本 Node.js サーバーとして稼働 ▪ ランタイムは Node.js 以外も選べる(次世代の話)

     → Edge Runtime  → 今日の研修では触れません Next.js の BFF とは システム構成によって使い分けることができる
  32. 第3章 Next.js の BFF ✅ Next.js は Web アプリケーションサーバーとして利用できる ▪ 単一

    Next.js プロジェクトコードで、フロント・ BFF 実装ができる ▪ 完全に静的なサイトジェネレーターとしても利用できる Next.js の BFF とは
  33. 第3章 Next.js の BFF 動的パラメーターの取得 ▪ gSSP の引数 ctx.query から query・path

    パラメーターが参照できる( 📌:3-2) ▪ gSSP が定義されている場合、 useRouter の挙動が変わる(📌:3-3) 【実技】SSR を試してみよう getServerSideProps あり getServerSideProps なし
  34. Cookie の参照 ▪ gSSP では Cookie の読み書きができる( 📌:3-4)  → nookies(Next.js で

    Cookie を扱いやすくするライブラリ) ▪ Cookie にセットした sessionID から、session 値を参照  → session 値を使用した外部リクエストなど 第3章 Next.js の BFF 【実技】SSR を試してみよう
  35. 第3章 Next.js の BFF ✅ gSSP はページのレンダリングだけでなく、リクエスト検証が行える ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC

    内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】SSR を試してみよう
  36. 第3章 Next.js の BFF SSR では環境変数が参照できる( 📌:3-6) ▪ gSSP で取得した環境変数は、 props

    を経由すると…  → フロントでも参照できてしまう  → やってはダメ 󰢃 【実技】環境変数を参照してみよう
  37. 第3章 Next.js の BFF コンポーネントから直参照するとどうなる?( 📌:3-7) ▪ NEXT_PUBLIC_ 接頭辞を持つ環境変数は、 client JavaScript

    のバンドルに含まれる ▪ NEXT_PUBLIC_ 接頭辞を持たない環境変数の直参照は、 Hydration エラーが発生 ▪ Hydration とは?  → 1. Server で生成した DOM を HTML 文字列化(SSR/SSG)  → 2. Client で HTML 文字列を DOM に復元する処理(イベントハンドラのアタッチ)  → 1・2の DOM に差があると、エラーが起こる( Hydration エラー) 【実技】環境変数を参照してみよう
  38. 第3章 Next.js の BFF .env には種類がある ▪ .env.production というファイルを用意すると、 production モードでのみ適用

     → $ npm run build && npm start  → http://localhost:3000/check_env_in_component ▪ .env*.local という名前でファイル作成すると、優先適用  → $ echo NEXT_PUBLIC_VAR=override_public_local > .env.local  → $ npm run dev  → .gitignore にあらかじめ設定されている  → .env は git 管理されてしまうので、クレデンシャル情報は含めないこと 【実技】環境変数を参照してみよう
  39. 第3章 Next.js の BFF ✅ 環境変数定義の方法が豊富 ▪ .env ファイルを使用することで、環境変数が定義できる ▪ サーバーランタイムだけでなく、ブラウザランタイムでも参照できる

     → 「NEXT_PUBLIC_」接頭辞をつける  → 露出して問題ない定数か注意する ▪ ビルドモードによって設定を細かく指定できる ▪ 環境変数はビルドタイムで決まる  → ランタイムで決める方法もある  → https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration 【実技】環境変数を参照してみよう
  40. 第3章 Next.js の BFF API Routes とは? ▪ Next.js が提供する Web

    API の構築方法 ▪ getServerSideProps と同様にサーバーサイドの処理ができる ▪ SPA で必要になる Web API が実装できる 【実技】Web API を試してみよう
  41. 第3章 Next.js の BFF Cookie を使用した counter 実装(📌:3-8) ▪ http://localhost:3000/api/counter/memory ▪

    リクエストを送るごとにインクリメント ▪ カウントは共有される 【実技】Web API を試してみよう トップレベル変数はサーバーメモリに(実際はこんな実装はほぼしない)
  42. 第3章 Next.js の BFF Cookie を使用した counter 実装(📌:3-9) ▪ http://localhost:3000/api/counter/cookie ▪

    リクエストを送るごとにインクリメント ▪ カウントは共有されない 【実技】Web API を試してみよう getServerSideProps と同様に Cookie を扱える
  43. 第3章 Next.js の BFF ✅ API Routes はリクエスト検証付きの Web API 実装ができる

    ▪ 基本、ブラウザに表示された UI コンポーネントから利用される Web API  → 値をフォームに入力・ボタンを押下  → 値を送信する先が、 API Routes(Web API) ▪ ログインユーザーに紐づいた情報の取得 ▪ VPC 内のバックエンド API サーバー(サブシステム)との連携に ▪ サーバーで実行されるため、クレデンシャル情報を扱える 【実技】Web API を試してみよう
  44. 第3章 Next.js の BFF Next.js が Fullstack フレームワークと呼ばれる所以 ▪ SSR(getServerSideProps) ▪

    Web API(API Routes) ▪ middleware 機能もある ✅ SPA と BFF を同時に構築できる Next.js は SPA フレームワークであり、 Web アプリケーションサーバーとして利用できる
  45. チャンクファイルとは? ▪ 一塊の JavaScript バンドルファイル ▪ ビルド時に確認できる  → ページ毎の First Load

    第4章 Next.js と パフォーマンス チャンクファイルの分割 First Load JS 量がグリーンのページはバンドルサイズが十分小さく、良好なページ
  46. チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移

    画面遷移 HTML 単一の HTML ファイル・JavaScript バンドルをレスポンス(古典的な SPA ) 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト
  47. チャンクファイルが分割されないとどうなるのか? ▪ どのエントリーポイント(ページのリクエスト)でも、全ページ分の取得 Web サーバー 第4章 Next.js と パフォーマンス チャンクファイルの分割 画面遷移

    画面遷移 HTML つまり、ページが増えるほどアプリの起動が遅くなる 大量のJavaScript 課題 JSON JSON /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト
  48. 第4章 Next.js と パフォーマンス Next.js に限らず、SPA メタフレームワークは Web サーバーも含む ▪ リクエストに応じて、対応するページを返却

    チャンクファイルの分割 必要最低限のJavaScript 必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト Web サーバー(Next.js) 分割 分割 分割
  49. 第4章 Next.js と パフォーマンス 静的ファイルだけで構成される時(静的サイトの場合)も分割される ▪ 動的ルートページを含む場合、 Web サーバー(Nginx 等)でルーティングが必要            → 分割されるため、静的サイトでも

    Next.js 採用にメリット チャンクファイルの分割 必要最低限のJavaScript 必要最低限のJavaScript 必要最低限のJavaScript /page-a /page-b /page-c /page-a のリクエスト /page-b のリクエスト /page-c のリクエスト Web サーバー(Nginx 等) 分割 分割 分割
  50. 第4章 Next.js と パフォーマンス ✅ ブラウザに送信する JavaScript バンドルサイズはパフォーマンスに直結する ▪ Next.js に限った話ではない。

    JavaScript バンドルサイズ削減が求められる ▪ フレームワーク・ライブラリは JavaScript バンドルサイズを減らす工夫を続けている  → granular chunking  → https://web.dev/granular-chunking-nextjs/ ▪ 最新の React 18 で追加された Server Components は、バンドルサイズの削減に繋がる チャンクファイルの分割 React・Next.js は、パフォーマンス向上を目的として進化
  51. 第4章 Next.js と パフォーマンス 事前レンダリングとは? ▪ リクエスト発生前に、ページをレンダリングしておくこと ▪ 事前レンダリングを適切に選択すると、  → オリジンサーバー( Next.js)の処理(負荷)を軽減できる

     → リソースサーバー( Backend API サーバー)へのアクセスも減る ▪ システム全体を俯瞰して、パフォーマンス面でのメリットが生まれる 事前レンダリング SSG(SG)と呼ばれるページレンダリング手法
  52. 第4章 Next.js と パフォーマンス SSG/SSR すると SPA にはならない? ▪ ページに直アクセスした場合、 HTML

    を得る ▪ SPA ナビゲーションでページにアクセスした場合、 JSON を得る ▪ 画面回遊においては、ページのリソースとなる JSON を都度取得する 事前レンダリング /page-a /page-b /page-c A B C /page-c /page-a /page-b C A B
  53. 第4章 Next.js と パフォーマンス SSG/SSR すると SPA にはならない? → NO ▪

    直接アクセス・SPA ナビゲーションに備え「両方」用意される  → 事前レンダリングは、 HTML・JSON を静的ファイルとして両方出力する ▪ SSR ページはリクエストに応じて、 HTML・JSON を都度出し分ける  → getServerSideProps は、HTML を SSR するだけの関数ではない! 事前レンダリング /page-a A /page-b B /page-c C
  54. 第4章 Next.js と パフォーマンス リクエスト前にあらかじめ出力するので、パブリックなページ向け ▪ パーソナルなページには使えない  → パーソナルなページの CDN キャッシュ → キャッシュ事故 󰢃

    ▪ 画面構成に応じて選ぶ  → ページの大部分がパーソナル  → SSR  → ページの小部分がパーソナル  → SSG + CSR 事前レンダリング
  55. 第4章 Next.js と パフォーマンス リクエスト前にあらかじめ出力するので、パブリックなページ向け ▪ パーソナルなページには使えない  → パーソナルなページの CDN キャッシュ → キャッシュ事故 󰢃

    ▪ 画面構成に応じて選ぶ  → ページの大部分がパーソナル  → SSR  → ページの小部分がパーソナル  → SSG + CSR 事前レンダリング SSR は遅い? → NO / 画面構成によっては SSR の方が速い(LCP※1 , FID 観点) ※1 LCP(Largest Contentful Paint)コアウェブバイタルの指標の 1つ。ユーザーの認識としてのページ表示速度を測る指標。
  56. 第4章 Next.js と パフォーマンス .next というディレクトリに、静的ファイルが出力される ▪ Vercel の場合  → .next ディレクトリが

    CDN に同期され、静的ファイルとして配信 ▪ Self-Hosting の場合  → .next ディレクトリを共有マウントで管理する必要がある 事前レンダリング .next ディレクトリを眺めながら、事前レンダリングの挙動を確認していきます
  57. 第4章 Next.js と パフォーマンス あらかじめ Backend API サーバーを起動しておきます ▪ カレントディレクトリを移動して  → $

    cd packages/backend-api ▪ Backend API サーバーを起動しておく  → $ npm run dev  → http://localhost:8080/api/now 【実技】事前レンダリングを試してみよう モックのニュースデータを返す Express API サーバー
  58. 第4章 Next.js と パフォーマンス production モードで起動して、3 種類のレンダリングの違いを確認してみよう ▪ $ npm run

    build でビルドする ▪ packages/chapter-4/.next に出力される静的ファイルを確認しよう  → .next/server/pages/news/isr に静的ファイルが出力されていない  → .next/server/pages/news/ssg に静的ファイルが出力されている  → .next/server/pages/news/ssr に静的ファイルが出力されていない ▪ $ npm start で起動する ▪ $ npm run restart で再ビルド・起動する 【実技】事前レンダリングを試してみよう 事前レンダリングの挙動をデバッグするためには、本番サーバーを起動する必要があります
  59. 第4章 Next.js と パフォーマンス .next というディレクトリの事前レンダリングファイル ▪ Vercel の場合  → .next ディレクトリが

    CDN に同期され、静的ファイルとして配信 ▪ Self-Hosting の場合  → .next ディレクトリを共有ボリュームで管理する必要がある 【実技】事前レンダリングを試してみよう
  60. 第4章 Next.js と パフォーマンス SSR ページの挙動(📌:4-1、📌:4-2) ▪ http://localhost:3000/news/ssr にアクセスしてみよう ▪ Backend

    API サーバーには、都度リクエストが発生する 【実技】事前レンダリングを試してみよう Backend API サーバーのアクセス時刻( accessedAt)は都度更新される
  61. 第4章 Next.js と パフォーマンス SSG ページの挙動(📌:4-3、📌:4-4) ▪ http://localhost:3000/news/ssg にアクセスしてみよう ▪ Backend

    API サーバーには、一切リクエストが発生しない Backend API サーバーのアクセス時刻( accessedAt)は一切更新されない 【実技】事前レンダリングを試してみよう
  62. 第4章 Next.js と パフォーマンス ISR(Incremental Static Regeneration)ページの挙動(📌:4-5、📌:4-6) ▪ http://localhost:3000/news/isr にアクセスしてみよう ▪

    Backend API サーバーには、稀にリクエストが発生する ▪ 再発生する間隔は 4 秒 【実技】事前レンダリングを試してみよう Backend API サーバーのアクセス時刻( accessedAt)は稀に更新される
  63. …ただしビルド時間が伸びる ▪ 事前レンダリングページ数 x Backend API 速度 = ビルド時間 第4章 Next.js

    と パフォーマンス 【実技】事前レンダリングを試してみよう 数万・数十万ページの事前レンダリングは、現実的ではない Backend API 遅延なしビルド Backend API 遅延ありビルド
  64. ビルド時に事前レンダリングするページは、指定できる( 📌:4-8) ▪ getStaticPaths 関数の paths 配列の文字列数  → .next/server/pages/news/ssg に出力される静的ファイル数 第4章 Next.js と

    パフォーマンス 【実技】事前レンダリングを試してみよう paths 配列が 0件の場合、ビルド時間は変わらない Backend API 遅延なしビルド Backend API 遅延ありビルド
  65. 第4章 Next.js と パフォーマンス Link コンポーネントからの被リンクで、投機的な事前レンダリング ▪ prefetch: false の場合リンク先ページは「事前レンダリングされない」( 📌:4-9)

     → ただし、マウスオーバーで「事前レンダリングされる」 ▪ prefetch: true の場合リンク先ページが「事前レンダリングされる」( 📌:4-10)  → ただし、Link コンポーネントが画面に表示されそうなとき  → Intersection Observer API が内部で使用されている  → https://github.com/vercel/next.js/blob/canary/packages/next/src/client/link.tsx#L509-L560 【実技】事前レンダリングを試してみよう prefetch 未指定の場合はどっち?( 📌:4-11)
  66. 第4章 Next.js と パフォーマンス 【実技】事前レンダリングを試してみよう Request: /page-a ユーザーの裏側で再生成 page-a.html page-a.html page-a.json

    Response: /page-a page-a.html Navigate: /page-b TTFB TTFB page-b.html page-b.json Revalidate Fetch Data Old page-b.json Fetch Data Old New
  67. 第4章 Next.js と パフォーマンス 投機的な事前レンダリングがされる条件( ISR の場合) ▪ 事前レンダリング対象ページの、静的出力が「ない」こと ▪ 事前レンダリング対象ページの、静的出力が「ある」場合

     → 投機的な事前レンダリングは発動しない  → ページ遷移先の「出力済み」の JSON を返す  → Revalidate 期間が経過していた場合、裏側で「再出力」を試行   → 次回アクセス時は、最新のページに更新されている   → Stale-White-Revalidate ※1 の挙動 【実技】事前レンダリングを試してみよう ユーザーには 出力済みの JSON を即レスポンスし、裏側で重たい再出力が試行されている ※1 Stale-While-Revalidate ヘッダによるブラウザキャッシュの非同期更新: https://blog.jxck.io/entries/2016-04-16/stale-while-revalidate.html
  68. 第4章 Next.js と パフォーマンス ✅ Link コンポーネントは、ナビゲーション目的だけじゃない ▪ 事前レンダリング対象ページは、被 Link によって投機的に生成される

    ▪ 投機的な事前レンダリングは  → ハイパフォーマンスな配信になり得る 👍  → 過剰な API 呼び出しになり得る 👎 ▪ SSR は投機的な事前レンダリング対象にならない 【実技】事前レンダリングを試してみよう 事前レンダリングのトリガーになる特別なコンポーネント
  69. ✅ 「オンデマンド」に静的ファイルが出力される ▪ 事前レンダリングの「事前」とは?  → 󰢃 ビルド時 / 󰢐 ページリクエストが発生しそうな時(誰かの行動起因) ▪ 事前レンダリングは、 HTML

    と JSON が同時出力される ▪ getStaticPaths 関数の fallback は、オンデマンド生成のオプション  → 生成完了前に、サーバーがレスポンスするかの設定値 ▪ getStaticProps 関数の revalidate は、オンデマンド再生成の間隔  → 秒数指定することで、 SSG は ISR になる 第4章 Next.js と パフォーマンス 【実技】事前レンダリングを試してみよう Next.js は SSR や Web API 機能を備え、オンデマンド SSG/ISR 機能を提供する
  70. 第4章 Next.js と パフォーマンス 【Appendix】Next.js v12.2 で追加された新機能 ▪ On-Demand Revalidation  → 既に生成したページを、要求されたタイミングで再生成する

     → API Routes に実装する(📌:4-12) ▪ データソースが更新されたタイミングで呼び出す  → 例えば、CMS が更新された直後に再生成、など 【実技】事前レンダリングを試してみよう ISRの「一定時間経過後に再生成」というざっくりとした指定よりも緻密になった
  71. 第5章 Next.js と ライブラリ アプリケーション実装は、 Next.js だけでは賄えない複雑さがある ▪ データ取得前のリクエスト検証  → バリデーションライブラリが欲しい( Zod)

    ▪ フォーム実装が複雑になりがち  → フォーム実装ライブラリが欲しい( React Hook Form) Next.js と一緒によく使用されるライブラリ 最近よく採用するこの 2つのライブラリを紹介します
  72. 第5章 Next.js と ライブラリ オブジェクトをパースして検証( 📌:5-2) ▪ 互換性がない場合、エラー ▪ 互換性がある場合、型推論に反映される  → value:

    z.string() を value: z.number() に変更してみよう  → data.value の型推論はどうなる? 【実技】Zod を使ってみよう
  73. 第5章 Next.js と ライブラリ ✅ 静的解析(TypeScript)とランタイム検証が同時に行える ▪ 不確かな値を扱う時、どこでも活用できる ▪ バリデーション済みのオブジェクトは、型推論に反映される ▪

    Zod 使用を前提としたエコシステムが人気  → tRPC、Zodios,、resolver(React Hook Form) ▪ 最近 Next.js 本体 devDependencies にも追加された  → https://beta.nextjs.org/docs/configuring/typescript#statically-typed-links  → https://github.com/vercel/next.js/pull/46962 【実技】Zod を使ってみよう
  74. 第5章 Next.js と ライブラリ React Hook Form の概要 ▪ フォームを扱う処理は複雑になりがちである  → フォームを簡単に実装できる

     → 高パフォーマンス(再レンダリング観点)で実装できる  → 非制御コンポーネントを使用したフォーム 【実技】React Hook Form を使ってみよう
  75. 第5章 Next.js と ライブラリ 通常盤:制御コンポーネントを使用したもの ▪ フォームの入力値とエラーメッセージを管理する状態を用意する( 📌:5-3) ▪ 制御コンポーネントを設置し、状態(入力値)を更新する ▪

    入力値更新のたびに、再描画が走る ▪ 送信を試みると、バリデーションとログイン処理を試行する( 📌:5-4) ▪ バリデーション・エラーメッセージ更新・ログイン処理を順番に実施  → ✅ 送信前のバリデーションやエラー掲出を実装するには、それなりの処理が必要 【実技】React Hook Form を使ってみよう
  76. 第5章 Next.js と ライブラリ React Hook Form 版:非制御コンポーネントを使用したもの ▪ 非制御コンポーネントとは ▪

    React で値を管理せず、DOM が保持する値を参照する ▪ (📌:5-5)入力フォームのバリデーションを行うスキーマを用意する ▪ (📌:5-6)Zod のスキーマを指定する ▪ (📌:5-7)register、formState を使用した非制御コンポーネント(入力要素)を設置  → register 関数を展開すると、非制御コンポーネントに必要な props が展開される ▪ (📌:5-8)バリデーションに成功したらログイン処理を実行する ▪ (📌:5-9)API Routes 側でもバリデーションを行う 【実技】React Hook Form を使ってみよう
  77. 第6章 簡単なアプリを作ろう ORM ライブラリの Prisma を使ってみよう ▪ Prisma ざっくり概要  → Prisma Schema

    Language(PSL)でスキーマを書く  → スキーマから、各言語向けの Client が生成できる  → スキーマから、マイグレーションファイルが生成できる  → TypeScript との親和性が高い 今日の研修では Prisma 詳説はしません。予め用意したスキーマで開発を進めます。 【実技】簡単なアプリを作ってみよう https://www.prisma.io/docs
  78. 第6章 簡単なアプリを作ろう 研修リポジトリの「packages/chapter-6」を使用します ▪ カレントディレクトリを移動して  → $ cd packages/chapter-6 ▪ $ docker

    compose up -d  → posgres サーバー が立ち上がっていることを確認 【実技】簡単なアプリを作ってみよう
  79. 第6章 簡単なアプリを作ろう ORM ライブラリの Prisma を使ってみよう ▪ Prisma をセットアップしよう ▪ $

    npm run db:migrate  → マイグレーション、 seeding を実行 ▪ リセットは $ npm run db:migrate:reset で 【実技】簡単なアプリを作ってみよう
  80. 第6章 簡単なアプリを作ろう ORM ライブラリの Prisma を使ってみよう ▪ Prisma Studio を使ってみよう  → Prisma

    に標準バンドルされている GUI  → $ npm run db:studio で Prisma Studio たちあげ  → $ http://localhost:5555 にアクセス 【実技】簡単なアプリを作ってみよう ✅ fixture が DB に挿入されていることを確認
  81. 第6章 簡単なアプリを作ろう ORM ライブラリの Prisma を使ってみよう ▪ Prisma Studio でレコードを追加してみよう  → Add

    record ボタンを押下  → 新規内容を入力して  → Save 1 change ボタンを押下 【実技】簡単なアプリを作ってみよう ✅ Prisma Studio で、DB を操作できます
  82. 第6章 簡単なアプリを作ろう 一連の CRUD 処理を確認しよう ▪ (📌:6-1)Postテーブルから全件取得 ▪ (📌:6-2)Postテーブルから ID が一致するレコードを取得

    ▪ (📌:6-3)サーバーで取得したデータを、初期値として設定 ▪ (📌:6-4)ID が一致するレコードを更新 【実技】簡単なアプリを作ってみよう
  83. 第6章 簡単なアプリを作ろう 【課題】次の機能を追加で実装してみてください ✏ ① 記事を書く時「128文字以内の本文」を送信できるようにしてみよう ✏ ② 本文を編集できるようにしてみよう ✏ ③

    記事にタグを付けられるようにしてみよう ✏ ④ タグで記事一覧をフィルターできる機能を追加してみよう ✏ ⑤ 新規タグを作成できる機能を追加してみよう ✏ ⑥ タグテーブルのクエリーを減らすにはどうすれば良いか検討してみよう ⏰ 制限時間まで、自由に作り込んでみてください※ 【実技】簡単なアプリを作ってみよう