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

Deep dive into Nuxt Server Components

wattanx
October 19, 2024

Deep dive into Nuxt Server Components

Vue Fes Japan 2024

wattanx

October 19, 2024
Tweet

More Decks by wattanx

Other Decks in Technology

Transcript

  1. Agenda 3 Nuxt のレンダリングモードと課題 Nuxt Server Components について Nuxt Server

    Components の活用方法 作って学ぶ Nuxt Server Components 他の似たような技術との違い 01 02 03 04 05
  2. Nuxt のレンダリングモードについて (Client-Side Rendering) Browser Server GET / GET /bundle.js

    Render JS をダウンロードする レンダリングされる 空の HTML を ダウンロードする HTML JS
  3. Nuxt のレンダリングモードについて (Client-Side Rendering) • パフォーマンス ◦ ブラウザが JavaScript をダウンロードし、解析・実行するのを待

    たなければならない ◦ そのため、コンテンツが表示されるまで遅い • 検索エンジンの最適化 ◦ クローラーとの相性が悪い ◦ JavaScript を解釈できるクローラーもあるが...
  4. Nuxt のレンダリングモードについて (Server-Side Rendering) • Client-Side Rendering の課題を解決する • Server

    は完全にレンダリングされた HTML をブラウザに返す Server-Side Rendering(Universal Rendering)
  5. Nuxt のレンダリングモードについて (Server-Side Rendering) Browser Server GET / GET /bundle.js

    Hydration HTML JS レンダリング済みの HTML をダウンロードする JS をダウンロードする Hydration される Render
  6. Nuxt のレンダリングモードについて (Server-Side Rendering) • Server から受け取った HTML を Interactive

    にする ◦ Server から受け取った HTML はイベントリスナがセット されていない ◦ イベントリスナをセットする作業が Hydration Hydration とは
  7. Nuxt Server Components • Nuxt 3 から導入された機能 ◦ まだ experimental

    • Server でだけレンダリングされるコンポーネントをつくることが できる Nuxt Server Components
  8. Nuxt Server Components • Server でだけ実行されて、Hydration されない ◦ Client bundle

    に不要な JS も含まれない • Server が必須ではない。 ◦ ビルド時にアプリケーションで使用される Server Component を プリレンダリングする ◦ そのため、完全に静的なサイトであっても動作する
  9. Nuxt Server Components Server Component 使わない場合 Server Component 使う場合 約

    66.4 % 減 詳しいソースコード https://github.com/wattanx/mini-nuxt-sc/pull/1
  10. Nuxt Server Components 使う側は import なしで使用する もしくは #components からの import

    (実際のパスから import するのはまだサポートできていない)
  11. Nuxt Server Components • Server Component の基盤 ◦ .server.vue は

    NuxtIsland コンポーネントを使ったコー ドに変換される • components/islands にコンポーネントを作ると、Server で だけレンダリングできるコンポーネントになる NuxtIsland コンポーネント
  12. Nuxt Server Components • Async Component が使える • Server Component

    と Client Component を入れ子にできる • Server Component のうち、一部だけ Hydration できる Nuxt Server Components でできること(一部抜粋)
  13. Nuxt Server Components の活用方法 • 時限式のコンポーネント ◦ https://www.mizdra.net/entry/2024/08/27/190853 ◦ ある特定の日に表示するようなコンポーネント

    ◦ Client Component だと Client bundle にその日まで出したくな い情報が含まれてしまう ◦ これは Nuxt Server Components においても効果的
  14. Nuxt Server Components の活用方法 • 頻繁に props が変更されるコンポーネント ◦ props

    が変わるたびに Server へのリクエストが発生するため Nuxt Server Components を活かせないもの
  15. Nuxt Server Components の活用方法 • Server Component 同士の入れ子 ◦ Server

    Component のレンダリングには Server へのリクエ スト が必要 ◦ なので、入れ子にするとオーバーヘッドが増える ◦ 理由は仕組みを理解するとわかる (このあと解説予定) 気をつけた方がいいところ
  16. 作って学ぶ Nuxt Server Components • Server Component の基盤である NuxtIsland •

    コンポーネントを Server でだけレンダリングする仕組み 最終的にできあがるもの
  17. 作って学ぶ Nuxt Server Components • Vue で Server-Side Rendering できる環境

    • npm create vite-extra@latest app -- --template ssr-vue-ts 準備するもの
  18. 作って学ぶ Nuxt Server Components Browser Server GET / GET /bundle.js

    Hydration HTML JS Render GET /__nuxt_island Render component HTML Not Hydrated
  19. 作って学ぶ Nuxt Server Components Browser Server GET / GET /bundle.js

    Hydration HTML JS Render GET /__nuxt_island Render component HTML Not Hydrated 従来のレンダリングとの差分
  20. 作って学ぶ Nuxt Server Components Nuxt Server Components の構成要素 • Vue

    コンポーネントをレンダリングするエンドポイント • Server で Vue コンポーネントをレンダリングする処理 • Vue コンポーネントをレンダリングするエンドポイントへリクエストを投げる コンポーネント
  21. 作って学ぶ Nuxt Server Components Nuxt Server Components の構成要素 • Vue

    コンポーネントをレンダリングするエンドポイント 👈 まずはここ • Server で Vue コンポーネントをレンダリングする処理 • Vue コンポーネントをレンダリングするエンドポイントへリクエストを投げる コンポーネント
  22. 作って学ぶ Nuxt Server Components Browser Server GET / GET /bundle.js

    Hydration HTML JS Render GET /__nuxt_island Render component HTML Not Hydrated ここ
  23. 作って学ぶ Nuxt Server Components • Server-Side Rendering 中に利用したいデータを追加できる ◦ Nuxt

    では Request Event を詰めたりしている ◦ useSSRContext を使うことでコンポーネント内からアクセ スできる • https://ja.vuejs.org/api/ssr.html#ssr-context SSR Context
  24. 作って学ぶ Nuxt Server Components Nuxt Server Components の構成要素 • Vue

    コンポーネントをレンダリングするエンドポイント • Server で Vue コンポーネントをレンダリングする処理👈 次はここ • Vue コンポーネントをレンダリングするエンドポイントへリクエストを投げる コンポーネント
  25. 作って学ぶ Nuxt Server Components Browser Server GET / GET /bundle.js

    Hydration HTML JS Render GET /__nuxt_island Render component HTML Not Hydrated ここ
  26. 作って学ぶ Nuxt Server Components createSSRApp と renderToString、 動的にコンポーネントをレンダリングする処理を組み合わせる Server で

    Vue コンポーネントをレンダリングする 動的にコンポーネントをレンダリングする
  27. 作って学ぶ Nuxt Server Components Nuxt Server Components の構成要素 • Vue

    コンポーネントをレンダリングするエンドポイント • Server で Vue コンポーネントをレンダリングする処理 • Vue コンポーネントをレンダリングするエンドポイントへリクエストを投げる コンポーネント 👈 次はここ
  28. 作って学ぶ Nuxt Server Components Browser Server GET / GET /bundle.js

    Hydration HTML JS Render GET /__nuxt_island Render component HTML Not Hydrated ここ
  29. 作って学ぶ Nuxt Server Components だいぶ簡略化したコード /__nuxt_island へリクエストを投げる Server でレンダリングされているので Client-Side

    ではprops が変わったらリクエストを投げる HTML 文字列 レンダリングする Hydration されない
  30. 作って学ぶ Nuxt Server Components Client Component を入れ子にするために必要なこと • <slot />

    をビルド時に独自の placeholder に変換する • Slot のコンテンツを Teleport で囲んでレンダリングする • placeholder 部分に Slot のコンテンツを差し込む
  31. 作って学ぶ Nuxt Server Components Client Component を入れ子にするために必要なこと • <slot />

    をビルド時に独自の placeholder に変換する 👈 まずはここ • Slot のコンテンツを Teleport で囲んでレンダリングする • placeholder 部分に Slot のコンテンツを差し込む
  32. 作って学ぶ Nuxt Server Components Client Component を入れ子にするために必要なこと • <slot />

    をビルド時に独自の placeholder に変換する • Slot のコンテンツを Teleport で囲んでレンダリングする 👈 次はここ • placeholder 部分に Slot のコンテンツを差し込む
  33. 作って学ぶ Nuxt Server Components Client-Side Rendering 時 Server-Side Rendering 時

    Teleport 部分をわかりやすいように書くと以下のようなコードになる
  34. 作って学ぶ Nuxt Server Components • コンポーネントにあるテンプレートの一部を、そのコンポー ネントの DOM 階層の外側に存在する DOM

    ノードに「テレ ポート」できる組み込みコンポーネント • https://ja.vuejs.org/guide/built-ins/teleport.html Teleport
  35. 作って学ぶ Nuxt Server Components Server-Side でレンダリングしたとき、SSR Context の teleports に

    Teleport 内のコンテンツが公開される (SSR Context は renderToString の第二引数に渡すオブジェクト) https://ja.vuejs.org/guide/scaling-up/ssr.html#teleports
  36. 作って学ぶ Nuxt Server Components Client Component を入れ子にするために必要なこと • <slot />

    をビルド時に独自の placeholder に変換する • Slot のコンテンツを Teleport で囲んでレンダリングする • placeholder 部分に Slot のコンテンツを差し込む 👈 次はここ
  37. 作って学ぶ Nuxt Server Components • Minimal Nuxt Server Components •

    Nuxt に依存しないように作った • Vue を使えば作れる https://github.com/wattanx/mini-nuxt-sc
  38. 他の似たような技術との違い • バンドル前に事前にレンダーされるコンポーネント • Server がなくても実行できる (Nuxt と同じ) • RSC

    Payload と呼ばれる特別なデータ形式にレンダリングされる ◦ Nuxt Server Components は HTML にレンダリングされる React Server Components
  39. 他の似たような技術との違い • 静的な部分に動的(JS で Interactive)な部分を埋め込むアプローチ • Nuxt Server Components とは逆

    ◦ Nuxt は動的な部分に静的なコンテンツを埋め込むというアプローチ Island Architecture
  40. • Nuxt Server Components は動的な部分に静的なコンテンツを埋め込 む技術 • Nuxt Server Components

    を使うことで client bundle を減らすこと ができる • Nuxt Server Components は Teleport の使い方がおもしろい まとめ
  41. まとめ • Remote Source もレンダリングできる • Server Page を作ることができる •

    Lazy Server Component を作ることができる 話せていないことがいっぱいある