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

新卒研修でNext.js AppRouterを導入した 学びと反省

井内 将俊
September 12, 2023

新卒研修でNext.js AppRouterを導入した 学びと反省

2023年9月12日に登壇したThink! FRONTEND by DMM.comにて発表した資料です。

井内 将俊

September 12, 2023
Tweet

Other Decks in Programming

Transcript

  1. 新卒研修でNext.js AppRouterを導⼊した
    学びと反省
    井内 将俊

    View Slide

  2. © DMM.com
    プロフィール
    ❏ 所属
    ❏ LC開発部
    VC-グロースグループ
    (2023年4月新卒入社)
    ❏ 最近のお仕事
    ❏ ライブコミュニケーションサービスの配信画面UIの開発
    ❏ 領域:フロントエンド
    ❏ 趣味:お絵描き
    井内 将俊(いうち まさとし)
    バーチャルライブチャット配信キャラクター

    2

    View Slide

  3. © DMM.com
    イントロ
    ダクション
    3
    ❏ 新卒研修のチーム開発
    ❏ 開発したアプリの簡単な説明
    ❏ AppRouterと周辺技術(SSR/Next.js/RCS)の
    ざっくり説明
    ❏ チーム開発でAppRouterを導入した反省点
    ❏ ユーザーIDの保管場所
    ❏ 動的ルートの静的ページ生成
    ❏ まとめ・所感

    View Slide

  4. © DMM.com
    イントロ
    ダクション
    4
    ❏ 新卒研修のチーム開発
    ❏ 開発したアプリの簡単な説明
    ❏ AppRouterと周辺技術(SSR/Next.js/RCS)の
    ざっくり説明
    ❏ チーム開発でAppRouterを導入した反省点
    ❏ ユーザーIDの保管場所
    ❏ 動的ルートの静的ページ生成
    ❏ まとめ・所感

    View Slide

  5. © DMM.com
    新卒研修のチーム開発
    - フロントエンド
    - バックエンド
    - ネイティブアプリ
    - 機械学習
    - ブロックチェーン
    - スクラム
    - etc…
    3ヶ月以上の修行を経て....
    「Amazon Web Services、“Powered by AWS”ロゴ、[およびかかる資料で使用されるその他のAWS商標] は、米国その他の諸国に
    おける、Amazon.com , Inc.またはその関連会社の商標です。」
    5

    View Slide

  6. © DMM.com
    新卒研修のチーム開発
    - フロントエンド
    - バックエンド
    - ネイティブアプリ
    - 機械学習
    - ブロックチェーン
    - スクラム
    - etc…
    チームを組んでアプリを開発!💪🔥
    3ヶ月以上の修行を経て....
    6

    View Slide

  7. © DMM.com
    新卒研修のチーム開発
    - 異なる技術領域が得意な4~5名の新卒チームで2.5週間かけて
    アプリを開発
    - アプリ内容、技術選定 完全自由
    7
    チーム開発

    View Slide

  8. © DMM.com
    新卒研修のチーム開発
    - 異なる技術領域が得意な4~5名の新卒チームで2.5週間かけて
    アプリを開発
    - アプリ内容、技術選定 完全自由
    - Next.jsの新機能(AppRouter)を使ってみよう!
    8
    チーム開発

    View Slide

  9. © DMM.com
    イントロ
    ダクション
    9
    ❏ 新卒研修のチーム開発
    ❏ 開発したアプリの簡単な説明
    ❏ AppRouterと周辺技術(SSR/Next.js/RCS)の
    ざっくり説明
    ❏ チーム開発でAppRouterを導入した反省点
    ❏ ユーザーIDの保管場所
    ❏ 動的ルートの静的ページ生成
    ❏ まとめ・所感

    View Slide

  10. © DMM.com
    開発したアプリ
    社内イベントの開催/参加を一元管理することで

    社内交流を促進するイベント管理アプリ

    10

    View Slide

  11. © DMM.com
    開発したアプリ
    11
    手描きした

    マスコットキャラクター

    社内イベントの開催/参加を一元管理することで

    社内交流を促進するイベント管理アプリ


    View Slide

  12. © DMM.com
    イントロ
    ダクション
    ❏ 新卒研修のチーム開発
    ❏ 開発したアプリの簡単な説明
    ❏ AppRouterと周辺技術(SSR/Next.js/RCS)の
    ざっくり説明
    ❏ チーム開発でAppRouterを導入した反省点
    ❏ ユーザーIDの保管場所
    ❏ 動的ルートの静的ページ生成
    ❏ まとめ・所感
    12

    View Slide

  13. © DMM.com
    AppRouterとは?🤔
    Next.js 13で追加された、RSCを利用した新しいルータ実装
    - Next.js とは?🤔
    - SSR等の多機能を簡単に実行可能にするReactのフレームワーク
    - RCSとは?🤔
    - React Server Components の略称
    SSR(とCSR)、既存のNext.js、RSC を理解せずにAppRouterを学ぶと大
    混乱...
    13

    View Slide

  14. © DMM.com
    CSRとSSR
    CSR:Client Side Rendering(SPA)
    クライアント(ブラウザ)
    APIサーバ
    - 初回に一括で取得
    - クライアントのみでレンダリング
    - データ取得もクライアント
    ホスティングサーバ
    14

    View Slide

  15. © DMM.com
    CSRとSSR
    CSR:Client Side Rendering(SPA)
    クライアント(ブラウザ)
    APIサーバ
    - 初回に一括で取得
    - クライアントのみでレンダリング
    - データ取得もクライアント
    - 初回読み込みが遅い...
    - SEOに弱い....
    ホスティングサーバ
    15

    View Slide

  16. © DMM.com
    CSRとSSR
    SSR(Next.js)
    - サーバー側でも一部レンダリング
    - サーバー側でもデータ取得
    Node.jsサーバ
    クライアントに任せっきりにしない!
    こっちも頑張る
    16
    クライアント(ブラウザ)
    APIサーバ

    View Slide

  17. © DMM.com
    Next.js(Pages Router)によるSSR
    SSR(Next.js)の例
    SSRを行うには
    専用の関数を用いる
    17

    View Slide

  18. © DMM.com
    RSC(React Server Components)
    - サーバー上でレンダリングされる新種のReactコンポーネント
    - useState等の状態管理やWebAPIへのアクセスはできない
    18
    クライアントコンポーネント
    - これまで通りクライアントでレンダリングされるコンポーネント
    現在alpha版

    View Slide

  19. © DMM.com
    ここまでAppRouterの前知識
    19

    View Slide

  20. © DMM.com
    AppRouterとは?
    • Next 13で追加された新しいルーター実装
    • 今年5月に安定版になった
    • React Server Component (RSC) 上に構築される
    • デフォルトでは全てRSC
    • つまり全てサーバー側でレンダリングされる
    これまでの(Pages Router)では基本クライアント側で
    レンダリングされていた
    RSCの概念を理解していないと大きく混乱...
    20

    View Slide

  21. © DMM.com
    サーバーコンポーネント/クライアントコンポーネント
    AppRouter(RSC)ではコンポーネント単位でレンダリング場所を
    指定可能
    サーバー側でレンダリングされる
    →サーバーコンポーネント
    (従来通り)クライアント側でレンダリングされる
    →クライアントコンポーネント
    21
    デフォルトでは全てサーバーコンポーネント

    View Slide

  22. © DMM.com
    サーバーコンポーネント/クライアントコンポーネント
    AppRouter(RSC)ではコンポーネント単位でレンダリング場所を
    指定可能
    サーバー側でレンダリングされる
    →サーバーコンポーネント
    クライアント側でレンダリングされる
    →クライアントコンポーネント
    22
    デフォルトでは全てサーバーコンポーネント
    サーバーコンポーネント
    クライアントコンポーネント

    View Slide

  23. © DMM.com
    サーバーコンポーネントのメリット
    - サーバーコンポーネントを増やせばクライアントへ送られるバンドルサ
    イズが削減できる
    - サーバーコンポーネントでデータ取得を行えば、データが埋め込まれた
    HTMLをクライアントへ送られデータ表示が高速になる
    - クライアントのCPU使用量削減
    23

    View Slide

  24. © DMM.com
    可能な限り
    サーバーコンポーネントを使うぞ!😆
    24

    View Slide

  25. © DMM.com
    クライアントコンポーネントだらけ...😨
    AppRouterの機能も活用しきれてない😭
    25

    View Slide

  26. © DMM.com
    イントロ
    ダクション
    ❏ 新卒研修のチーム開発
    ❏ 開発したアプリの簡単な説明
    ❏ AppRouterと周辺技術(SSR/Next.js/RCS)の
    ざっくり説明
    ❏ チーム開発でAppRouterを導入した反省点(改善点)
    ❏ ユーザーIDの保管場所
    ❏ 動的ルートの静的ページ生成
    ❏ まとめ・所感
    26

    View Slide

  27. © DMM.com
    AppRouter導入反省点
    - ユーザーIDをクライアントの状態管理のみで保管してしまった
    - GenerateStaticParamsの機能を利用できてなかった
    27

    View Slide

  28. © DMM.com
    AppRouter導入反省点
    - ユーザーIDをクライアントの状態管理のみで保管してしまった
    - GenerateStaticParamsの機能を利用できてなかった
    28

    View Slide

  29. © DMM.com
    ユーザーIDの保管
    ・ユーザーID
    ログインしているユーザーのID
    ・Jotai
    状態管理ライブラリ
    Jotaiを用いてユーザーIDを保管し、何処のコンポーネントでも
    ユーザーIDを用いてユーザー固有のデータを取得できるように実装
    29

    View Slide

  30. © DMM.com
    ユーザーIDの保管
    ・ユーザーID
    ログインしているユーザーのID
    ・Jotai
    状態管理ライブラリ
    Jotaiを用いてユーザーIDを保管し、何処のコンポーネントでも
    ユーザーIDを用いてユーザー固有のデータを取得できるように実装
    30
    Jotaiを使わずにCookieに保存していればもっと
    サーバー側で取得可能なデータを増やせたのに....😭

    View Slide

  31. © DMM.com
    クライアントでの状態管理とcookie
    クライアントの状態管理(Redux, Recoil, Jotai, localStorage)
    - サーバーコンポーネントでは値が読み取れない...
    Cookie
    - ブラウザに保存されるデータ
    - cookieリクエスト毎にサーバーに送られる
    - サーバーコンポーネントでも値が読み取れる!
    31

    View Slide

  32. © DMM.com
    クライアントでの状態管理とcookie
    クライアントの状態管理(Redux, Recoil, Jotai, localStorage)
    - サーバーコンポーネントでは値が読み取れない...
    Cookie
    - ブラウザに保存されるデータ
    - cookieリクエスト毎にサーバーに送られる
    - サーバーコンポーネントでも値が読み取れる!
    32
    Next.jsでも全く同様
    △ AppRouter導入の反省    ⭕ SSR導入の反省

    View Slide

  33. © DMM.com
    サーバーコンポーネントで
    ユーザーIdが取得できて嬉しい例
    33

    View Slide

  34. © DMM.com
    cookieによるユーザーID取得のメリット
    サーバーコンポーネントで取得できるデータが増える
    34

    View Slide

  35. © DMM.com
    cookieによるユーザーID取得のメリット
    35

    View Slide

  36. © DMM.com
    cookieによるユーザーID取得のメリット
    誰が取得しても同じ
    (サーバー側で取得)
    ユーザーIDを用いてユーザーに紐
    づいたイベントを取得
    (クライアント側で取得)
    36

    View Slide

  37. © DMM.com
    cookieによるユーザーID取得のメリット
    誰が取得しても同じ
    (サーバー側で取得)
    ユーザーIDを用いてユーザーに紐
    づいたイベントを取得
    (クライアント側で取得)
    CookieにユーザーIdを入れれば全てサーバー側で取得可能
    37

    View Slide

  38. © DMM.com
    cookieを用いていない挙動
    38

    View Slide

  39. © DMM.com
    cookieを用いていない挙動
    39

    View Slide

  40. © DMM.com
    cookieを用いていない挙動
    40

    View Slide

  41. © DMM.com
    cookieでユーザーIDを管理した挙動
    41
    初回表示から全データ取得できてる...!

    View Slide

  42. © DMM.com
    cookieでユーザーIDを管理した挙動
    42
    Cookieの仕組みを
    ちゃんと理解していれば...😭

    View Slide

  43. © DMM.com
    AppRouter導入反省点
    - ユーザーIDをクライアントの状態管理のみで保管してしまった
    - GenerateStaticParamsの機能を利用できてなかった
    43

    View Slide

  44. © DMM.com
    GenerateStaticParams
    - "動的”ルーティングを使用し、ビルド時に”静的”なルートを生成
    - Pages RouterのgetStaticParamsに近い機能
    - getStaticParams:ビルド時にページを作成するSSGを行う機能
    - つまりSSG(Static Site Generation)ができる機能!
    44

    View Slide

  45. © DMM.com
    GenerateStaticParams
    - パス部分が動的に変化する
    ルーティング
    45
    アクセスを検知したら、パスから固有のデータ
    を取得しサーバー側でレンダリング

    View Slide

  46. © DMM.com
    GenerateStaticParams
    - パス部分が動的に変化する
    ルーティング
    46
    アクセスを検知したら、パスから固有のデータ
    を取得しサーバー側でレンダリング
    ビルド時に静的レンダリング(SSG)
    GenerateStaticParams

    View Slide

  47. © DMM.com
    使ってなかった場合
    47
    - パス情報からイベント詳細を取得するAPIを叩き、
    取得したイベントデータを使用してページを表示

    View Slide

  48. © DMM.com
    使ってなかった場合
    48
    - パス情報からイベント詳細を取得するAPIを叩き、
    取得したイベントデータを使用してページを表示

    View Slide

  49. © DMM.com
    使ってなかった場合
    49
    - パス情報からイベント詳細を取得するAPIを叩き、
    取得したイベントデータを使用してページを表示

    View Slide

  50. © DMM.com
    使ってた場合
    50
    事前にイベントデータを取得

    View Slide

  51. © DMM.com
    使ってた場合
    51
    事前にイベントデータを取得

    View Slide

  52. © DMM.com
    使ってた場合
    52
    事前にイベントデータを取得
    こんなに簡単にSSGができたのに
    勿体無い😭

    View Slide

  53. © DMM.com
    その他の反省
    - OGP
    - AppRouterのgenerateMetadataを用いて動的OGPを実装したが、
    そもそも本アプリはVPN接続してないと中身が見れないので
    OGPは不可能
    - ファイル構成
    - featuresディレクトリで機能ごとに分割
    - 構成の理解不足からファイル分割(コンポーネント分割)に支障が出て、
    クライアントコンポーネントが増えた
    - UIライブラリ選定
    - TailwindメインのUIにすればよりサーバーコンポーネント増やせた etc…
    53

    View Slide

  54. © DMM.com
    反省点しかない...?🤔
    54

    View Slide

  55. © DMM.com
    褒めたい点
    55
    - ちゃんと仕様通りに動くアプリが作れた
    - 技術的挑戦ができた
    - 多くの学びを得られた (これはあくまで新卒技術研修のチーム開発)

    View Slide

  56. © DMM.com
    まとめ・所管
    新卒技術研修のチーム開発にAppRouterを導入
    SSR,RSC,Cookie等の前提知識の不足から十分に活用できなかった
    56
    サーバーコンポーネント/SSG は目的ではなく手段
    フロントのパフォーマンス向上が目的
    - パフォーマンス測定の理解
    - Cache機能の理解

    View Slide

  57. © DMM.com
    おわり
    57

    View Slide