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

Next.js

Avatar for Recruit Recruit PRO
August 10, 2023

 Next.js

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

Avatar for Recruit

Recruit PRO

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文字以内の本文」を送信できるようにしてみよう ✏ ② 本文を編集できるようにしてみよう ✏ ③

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