Save 37% off PRO during our Black Friday Sale! »

より速い WEB を目指す Next.js / nextjs-make-the-web-faster

5d9cd19df0e91caac118b793b4f803d5?s=47 Takepepe
November 24, 2021

より速い WEB を目指す Next.js / nextjs-make-the-web-faster

【Next.js Update!】v12リリースを踏まえ、Next.jsの採用を考える

本発表は以下URLでアーカイブ視聴が可能です。https://youtu.be/KaS3bgz_CA4

イベントページ:https://forkwell.connpass.com/event/228457/

5d9cd19df0e91caac118b793b4f803d5?s=128

Takepepe

November 24, 2021
Tweet

Transcript

  1. より速い WEB を目指す Next.js 【Next.js Update!】 v12リリースを踏まえ、Next.jsの採用を考える

  2. 吉井 健文 / Takepepe 株式会社リクルート  APソリューショングループ フロントエンドエンジニア・アーキテクト

  3. Agenda ▪ 前半:Next.js Conf 2021 おさらい / ▪ 後半:Next.js 12

    発表をうけて ▪ Static x Dynamic ▪ React Server Components x Edge ▪ Next.js x Granular Renderings ▪ Next.js x Granular Prefetch ▪ Next.js x Granular Chunks
  4. Next.js Conf 2021 の発表 Next.js Conf 2021 における発表内容は、 Next.js・React 開発の転換期到来アナウンスとなりました。

    現時点では実験的な機能(beta / alpha版)が多いですが、 その発表内容は大きなインパクトがありました。
  5. Next.js Conf 2021 の参考資料 Next.js at the Edge - Suzanne

    Aldrich + Lee Robinson - (Next.js Conf 2021) https://www.youtube.com/watch?v=WlP2TB2ORL4 Blog - Next.js 12 https://nextjs.org/blog/next-12 前半36Pまでは、上の動画内容をおさらいします
  6. Static x Dynamic

  7. Next.js の歴史 Server-Side Rendering SSR Automatic Static Optimization Static Site

    Generation SSG Incremental Static Regeneration ISR Next.js は SSR framework としてスタート。
  8. Next.js の歴史 Server-Side Rendering SSR Automatic Static Optimization Static Site

    Generation SSG Incremental Static Regeneration ISR 続いて、Automatic Static Optimization を導入しました。
  9. Next.js の歴史 Server-Side Rendering SSR Automatic Static Optimization Static Site

    Generation SSG Incremental Static Regeneration ISR Static Site Generation を採用し、Hybrid Framework に。
  10. Next.js の歴史 Server-Side Rendering SSR Automatic Static Optimization Static Site

    Generation SSG Incremental Static Regeneration ISR ISR を採用し、リビルド不要でページ更新を可能に。
  11. Next.js の歴史 Server-Side Rendering SSR Automatic Static Optimization Static Site

    Generation SSG Incremental Static Regeneration ISR ページ単位で「きめ細かい (Granular) 」戦略を取れる仕組みを提供しました。
  12. Static vs Dynamic これまで Next.js が提供してきたソリューションで明るみになったのは ▪ Static(getStaticProps / getStaticPaths)

    ▪ Dynamic(getServerSideProps) この両者が、スピードとパーソナライズで対立していることでした。
  13. Static vs Dynamic SSR (動的) はリクエスト毎に HTML を算出しコンテンツをパーソナライズ。 Dynamic (Personalization)

    Static (Speed) SSR
  14. Static vs Dynamic しかし、一貫したパフォーマンス提供が困難でした。 Dynamic (Personalization) Static (Speed) SSR

  15. Static vs Dynamic SSG (静的生成) は Edge CDN キャッシュから静的配信し、高速な提供を実現。 Dynamic

    (Personalization) Static (Speed) SSG
  16. Static vs Dynamic しかし、リクエストに基づき HTML を変えるパーソナライズが失われました。 Dynamic (Personalization) Static (Speed)

    SSG
  17. この両者の強みを同時に発揮できるものとして Dynamic (Personalization) Static (Speed) Static x Dynamic =

  18. Static x Dynamic = Edge Next.js が選んだのが Edge というソリューションです。 Edge

    Dynamic (Personalization) Static (Speed)
  19. Static x Dynamic = Edge USER ORIGIN Edge (Computing) は

    CDN と同様に、ユーザーとオリジンの中間に位置します。 Edge
  20. Static x Dynamic = Edge USER ORIGIN この Edge で処理する仕組みとして

    middleware (beta) が導入されました。 Middleware
  21. Static x Dynamic = Edge middleware はリクエストに基づき、オリジン到達前にコードを実行します。 Middleware

  22. Static x Dynamic = Edge 書き換え(Rewrite) / リダイレクト(Redirecting) / ヘッダーの追加(Header)

    Middleware
  23. Static x Dynamic = Edge さらには HTML のストリーミング(Streaming) Middleware

  24. Static x Dynamic = Edge 物理的にユーザーに近いサーバーで Edge 関数を実行できます。 Middleware

  25. No Cold Starts, 100x Faster middleware は Vercel Edge Functions

    という厳密なランタイムで実行されます ▪ V8 を使用した JavaScript & WASMエンジンで構築されている ▪ fetch 関数など、標準の Web API ※ に限られる ▪ Native Node.js API はサポート外(fs等) ▪ Native Node.js API に非依存の node_modules は利用可 ※ 標準の Web API:ESM、Fetch、Stream、AbortController、など。 Web上のサービスが提供する RESTやGraphQL APIのことではない 【詳細】Edge Runtime https://nextjs.org/docs/api-reference/edge-runtime
  26. No Cold Starts, 100x Faster この制限のある環境下において、 仮想マシン or コンテナで起動する Node.js

    よりも 100倍高速な起動を提供することが可能になっています。 100 x Faster
  27. No Cold Starts, 100x Faster middleware で可能な一例に、以下の機能が挙げられます ▪ Authentication ▪

    Bot Protection ▪ Redirects ▪ Browser Support ▪ Feature Flags ▪ A/B Testing ▪ Server-Side Analytics ▪ Logging
  28. No Cold Starts, 100x Faster 例えば geo location に応じ、 静的ページを出し分けることが

    可能になります。 【詳細】Next.js at the Edge https://youtu.be/WlP2TB2ORL4?t=368
  29. No Cold Starts, 100x Faster middleware はセルフホスティング環境であっても、 Next.js の標準的なビルドで利用可能に(Node.js の

    sandbox 内)※ Vercel にデプロイする場合、middleware は Edge に展開。 開発者はインフラ構成を気にすることなく、 デフォルトでこの機能が有効になります。 ※ セルフホスティング環境では「 No Cold Start, 100x Faster」にはなりません
  30. React Server Components x Edge

  31. React Server Components x Edge Next.js Conf 2021 で最大の驚きは(少なくとも私は) React

    チームと協力し React 18 サポートの準備を開始したこと、 そして React Server Components(aplha版)が Next.js で利用可能になるという発表です。 ※ React Server Components サポートは、React 18 サポートより未来になる認識 ※ React Server Components サポート時期について言及: https://github.com/reactwg/react-18/discussions/37
  32. React Server Components x Edge 従来 SSR (getServerSideProps) での課題 ▪

    データ取得完了まで、レスポンスを返却できない ▪ サーバーからのレスポンスを待つ間、真っ白な画面が表示される ▪ 全ての HTML が表示されるか否か
  33. React Server Components x Edge React Server Components x Edge

    で得られるメリット ▪ Edge 関数から即座に Streaming が開始されるため、待つ事がない ▪ 段階的にレンダリングを行い、完了したものから Streaming ▪ ブラウザ向け JS が最小限に、インタラクティブになるまでが高速に ▪ サーバー側で計算するため、非力なデバイスでも高速に
  34. React Server Components x Edge で得られるメリット ▪ Edge 関数から即座に Streaming

    が開始されるため、待つ事がない ▪ 段階的にレンダリングを行い、完了したものから Streaming ▪ ブラウザ向け JS が最小限に、インタラクティブになるまでが高速に ▪ サーバー側で計算するため、非力なデバイスでも高速に TTFB/ LCP/ FID など、Web Vitals 向上に貢献 React Server Components x Edge
  35. getServerSideProps / getStaticProps は将来不要に ▪ データフェッチ関数をコンポーネントと同じ場所に配置可能になる ▪ 必要に応じて最小限のスクリプトが送られ、段階的に Hydrate される

    ▪ 将来的に ISR の様な、ページ単位のキャッシュは必要なくなる ▪ その代わりに「コンポーネントレベル」で詳細なキャッシュが可能になる React Server Components x Edge
  36. granular component caching という展望 ▪ Suspense 境界のように機能する「Data」コンポーネントを検討している ▪ コンポーネント単位で surrogate

    keys を発行し個別でパージ可能に ▪ コンポーネント単位で revalidate 秒数指定が可能に ▪ React Server Components と Edge functions のイノベーションで可能になった React Server Components x Edge
  37. Next.js Conf 2021 感想

  38. Next.js Conf 2021 感想 発表は未来的で、驚きの多い内容でした。しかしながら、 実験的な内容ばかりで「実務ですぐに使える内容ではなさそう」 という感想を持った方も多いと思います。 そもそも、React Server Components

    を使う理由に、 いまいちピンと来てないかもしれません。
  39. まず、なぜ React や Next.js を使うのか、 明確な動機を考えてみましょう。 開発者体験でしょうか? それとも、要件に適合させやすい Hybrid な柔軟さでしょうか?

    いずれも正しいと思います。 Next.js Conf 2021 感想
  40. ひとつは、誰もがすぐに開発を始められることです。 Dan Abramov 氏が Create React App 発足の動機として語る様に、 過去、フロントエンド開発環境の準備は敷居が高いものでした。 Next.js

    Conf 2021 感想 Before CRA, the ecosystem was hopelessly fragmented. The entire category of tools like this didn't exist — there was no Next or Gatsby or Vite and so on. The vast majority of React developers were setting up their Babel, webpack, etc, manually, and having a really bad time. These tools were difficult to get working together correctly. ” ※ 引用:https://github.com/facebook/create-react-app/issues/11180
  41. Next.js Conf 2021 感想 今日、Next.js / Gatsby / Vite を利用すれば、あまり意識せずとも、

    フロントエンド開発のベストプラクティス恩恵を、 開発初期から受けることができます。 ※ 引用:https://github.com/facebook/create-react-app/issues/11180 Before CRA, the ecosystem was hopelessly fragmented. The entire category of tools like this didn't exist — there was no Next or Gatsby or Vite and so on. The vast majority of React developers were setting up their Babel, webpack, etc, manually, and having a really bad time. These tools were difficult to get working together correctly. ”
  42. 最も着目すべきは、React や Next.js が 「Web Vitals」を指針に、 「ユーザー体験向上を中心に進化」している点です。 React Server Components

    x Edge も 例外なくこの取り組みの一環だと思います。 Next.js Conf 2021 感想 ※ 引用:https://web.dev/vitals/
  43. Next.js Conf 2021 のデモにあったとおり、 React Server Components は HTML と

    最小限の JavaScript しか届けません。 細切れな生成済み HTML を段階的に hydrate するため、 低スペック端末でも快適な UX の提供が期待できます。 Next.js Conf 2021 感想
  44. React Server Components の恩恵が受けられると想定できるのは、 「処理速度・ネットワークが遅い」モバイル端末です。 (表示すべき HTML を最小限にとどめる効果も期待大) 配信するコンテンツがパーソナライズされたものであれば、 より高い効果が期待できます。

    Next.js Conf 2021 感想
  45. React Server Components の恩恵が受けられないケースもあると思います。 (現状は alpha 版なので、判断材料として不透明ですが) これは ISR が発表された時と同様に、

    「いくつかある選択肢が更に増えた」と受け止めています。 Next.js Conf 2021 感想
  46. Next.js x Granular Renderings

  47. 開発者が、以前も・これからも変わらず意識すべきことは 「ユーザー体験を中心に設計する」ということです。 Web Vitals を指針に改善し続けるという取り組みは、 開発者はもちろん、フレームワーク最大の関心ごとです。 Next.js x Granular Renderings

  48. Next.js はこれまで、ページ単位で Rendering を選択するという 「きめ細かい (Granular)」アプローチを提供してきました。 これが Web Vitals にどの様に貢献するのか、

    Next.js Conf 2021 で発表された新しい Rendering とあわせ、    ※ TTFB (Time To First Byte) サーバーの初期応答時間 / FCP (First Contentful Paint) 視覚コンテンツの初期表示時間 ※ LCP (Largest Contentful Paint) 最大視覚コンテンツの表示時間 / FID (First Input Delay) 初回入力までの遅延時間 LCP FID TTFB FCP を比較していきましょう。 Next.js x Granular Renderings
  49. Origin Server API Server/DB 従来 SSR はデータ取得完了後にレスポンスを送信、 TTFB が遅くなる傾向に。 Request

    【1】従来 SSR (Server-Side Rendering)
  50. Origin Server API Server/DB TTFB の遅れにより、Web Vitals が全体的に後ろ倒しになる。 FID LCP

    FCP Request TTFB 【1】従来 SSR (Server-Side Rendering)
  51. 【1】従来 SSR (Server-Side Rendering) ▪ リクエスト毎に算出するため、低パフォーマンス ▪ 常に新しいデータを取得するため、データ整合性が確実 ▪ パーソナライズ可能であり、個人情報なども表示できる

    ※ Cache-Control header が設定されていない前提であり、設定次第ではこの限りではありません
  52. Origin Server API Server/DB Edge CDN ビルド時に静的生成せず、オンデマンドで静的生成。 Request No Cache

    【2】ISR (fallback: “blocking”)
  53. Origin Server API Server/DB 静的 HTML Cache がない場合、TTFB までは実質 SSR

    と同じ。 FID Request LCP FCP TTFB No Cache 【2】ISR (fallback: “blocking”) Edge CDN
  54. Origin Server API Server/DB 生成した HTML は Edge CDN に

    Cache される。 FID Request Cache LCP FCP TTFB No Cache 【2】ISR (fallback: “blocking”) Edge CDN
  55. ▪ ビルドタイムに静的生成せず、オンデマンドで静的生成が可能 ▪ Cache がある場合、Edge CDN から HTML が返るため高速 ▪

    Cache がない場合、SSR と同様に Rendering を blocking ▪ クローラーにコンテンツを確実にインデックスさせたい場合に利用 【2】ISR (fallback: “blocking”)
  56. Origin Server API Server/DB Cache が無くても、コンテンツがない「Skeleton (= ...loading)」が返る。 FCP Request

    TTFB 【3】ISR (fallback: true) Edge CDN
  57. Origin Server API Server/DB データ取得が完了するまで、ページは「...loading」状態に。 FCP Request TTFB 【3】ISR (fallback:

    true) Edge CDN
  58. Origin Server API Server/DB データ取得が完了した後、ページが再描画される。 FID LCP FCP Request TTFB

    【3】ISR (fallback: true) Edge CDN
  59. Origin Server API Server/DB JSON と同時に静的 HTML が生成され、Edge CDN に

    Cache される。 FID LCP FCP Request TTFB Cache Cache 【3】ISR (fallback: true) Edge CDN
  60. ▪ ビルドタイムに静的生成せず、オンデマンドで静的生成が可能 ▪ Cache がある場合、Edge CDN から HTML が返るため高速 ▪

    Cache がない場合、Skeleton を返すため TTFB までが速い ▪ クローラーに Skeleton がインデックスされるリスクがあった 【3】ISR (fallback: true)
  61. ▪ ビルドタイムに静的生成せず、オンデマンドで静的生成が可能 ▪ Cache がある場合、Edge CDN から HTML が返るため高速 ▪

    Cache がない場合、Skeleton を返すため TTFB までが速い ▪ クローラーに Skeleton がインデックスされるリスクがあった Next.js 12 で追加された「Bot-Aware ISR Fallback」で心配なくなった。 【3】ISR (fallback: true) ※ Bot-Aware ISR Fallback の RFC:https://github.com/vercel/next.js/discussions/28180
  62. Origin Server API Server/DB 静的 HTML Cache が Edge CDN

    から高速に配信。 FCP Request TTFB 【4】Static (Cache) + CSR Edge CDN
  63. Origin Server API Server/DB パーソナライズが必要なコンテンツは、部分的に CSR を併用する。 FCP Request TTFB

    【4】Static (Cache) + CSR Edge CDN
  64. Origin Server API Server/DB Static Generation だけでなく、SSR でも用いられる構成。 FCP Request

    TTFB 【4】Static (Cache) + CSR LCP FID Edge CDN ※ LCP相当のコンテンツデータを fetch している前提
  65. Origin Server API Server/DB JS ファイルがロードされた後に hydrate、fetch が開始。LCP までが遅い。 LCP

    FCP Request TTFB 【4】Static (Cache) + CSR Slow FID Edge CDN ※ LCP相当のコンテンツデータを fetch している前提
  66. 【4】Static (Cache) + CSR ▪ Edge CDN の高速配信で TTFB を高速に

    ▪ JS ファイルのロード完了後に fetch が開始するため、LCP までが遅い ▪ 常に新しいデータを取得するため、データ整合性が担保できる ▪ 部分的にパーソナライズ可能であり、個人情報なども表示できる ※ LCP相当のコンテンツデータを fetch している前提
  67. ここから Next.js Conf 2021 で発表された 新しい Rendering 【5】Streaming with getServerSideProps

    (RFC) 【6】Streaming SSR @ Edge (alpha) 既存の getServerSideProps 拡張・React 17 でも使え【6】への移行を容易に
  68. ここから Next.js Conf 2021 で発表された 新しい Rendering 【5】Streaming with getServerSideProps

    (RFC) 【6】Streaming SSR @ Edge (alpha) React Server Components を使い、React 18 以降が必要
  69. Origin Server API Server/DB keynote とは別セッションで紹介された、getServerSideProps の拡張。 Request 【5】Streaming with

    getServerSideProps Edge CDN
  70. Origin Server API Server/DB コンテンツデータ (LCP 相当) を取得する前に <head />

    を返却、TTFB が速い。 FCP Request TTFB 【5】Streaming with getServerSideProps <head /> Edge CDN
  71. Origin Server API Server/DB そのため、従来 SSR と比較し CSS / JS

    ロードが前倒しに。 FCP Request TTFB 【5】Streaming with getServerSideProps コンテンツデータ (LCP相当) CSS / JS Edge CDN
  72. Origin Server API Server/DB データ取得が完了した段階で HTML の残りを flush し、ページを提供。 FID

    LCP FCP Request TTFB 【5】Streaming with getServerSideProps <body /> Edge CDN
  73. Origin Server API Server/DB ここが Streaming で、このレスポンスは <head /> と同じもの。

    FID LCP FCP Request TTFB 【5】Streaming with getServerSideProps Streaming Edge CDN
  74. 【5】Streaming with getServerSideProps ▪ Next.js 12 にはまだ搭載されておらず、RFC段階 ▪ getServerSideProps が返す「props」に変更が加えられる

    ▪ 従来 SSR のボトルネックであった、TTFB 遅延が改善 ▪ データ取得開始のタイミングが CSR より前なので LCP までが速い ▪ 次の【6】Streaming SSR@Edge への準備として有用 【詳細】Streaming in Next.js - Kara Erickson - (Next.js Conf 2021) https://youtu.be/Nl4OwNhh2QI?list=TLGG9L6VQs5dRz4xNTExMjAyMQ
  75. API Server/DB Edge Computing でも Skeleton を返却する FCP Request TTFB

    Edge Computing 【6】Streaming SSR @ Edge (alpha)
  76. API Server/DB データを取得し、HTML 生成が完了したものから Streaming FCP Request TTFB 【6】Streaming SSR

    @ Edge (alpha) Edge Computing
  77. API Server/DB 断片的に送られてきた HTML を順次 Hydrate する FID LCP FCP

    Request TTFB 【6】Streaming SSR @ Edge (alpha) Edge Computing
  78. API Server/DB React Server Components の初期表示にはこの Streaming SSR が使われる。 FID

    LCP FCP Request TTFB 【6】Streaming SSR @ Edge (alpha) Streaming Edge Computing
  79. 【6】Streaming SSR @ Edge (alpha) ▪ まだ試験的な段階で、一部機能が試せるようになったばかり ▪ Edge からの

    Streaming 配信により、全ての高速化が期待される ▪ インフラを自由に選択できるのは、さらに将来の話になりそう 【詳細】Next.js at the Edge - Suzanne Aldrich + Lee Robinson - (Next.js Conf 2021) https://www.youtube.com/watch?v=WlP2TB2ORL4
  80. Next.js x Granular Renderings まとめ

  81. Next.js x Granular Renderings レンダリング手法は多岐にわたりますが、共通点があります。 それは、データ取得が必要なコンテンツを分割し 「早期に Skeleton を返却、TTFB を高速化する」という点です。

    これは引き続き、重要なパートになります。
  82. Next.js x Granular Renderings ▪ コンテンツの性質に応じた Rendering が選択できているか ▪ 静的事前生成エリア・データ取得エリアは、適切に分離できているか

    ▪ Skeleton のデザインは考慮されているか パフォーマンスのために、デザイン面でも積極的に議論を。
  83. Next.js x Granular Prefetch

  84. Next.js x Granular Prefetch 提供されている Granular Renderings を選ぶだけでは、 3つの Core

    Web Vitals の指標のうち「CLS」の対策がとれません。 「視覚的な安定性」は、コンテンツの高さ変動に起因します。 これは Suspense の様な多段レンダリングはもちろん、 ...loading 表示(Skeleton 表示)についてまわる課題です。 ※ CLS(Cumulative Layout Shift)「累積レイアウト シフト数」視覚的な安定性を測定するための指標。
  85. Next.js x Granular Prefetch ここで活きるのが「SWR」等のライブラリです。 Suspense と似たコンポーネント構成を取ることができ、 CSR における非同期データ取得を簡単にしてくれます。 そして

    Navigation に伴う ...loading 表示を削減し、 視覚的に安定した Navigation を提供できます。 ※ 以降「 Navigation 」は SPA における遷移を指します
  86. CSR (Each Request) Edge / Origin API Server/DB あるページからの Navigation

    で、データを取得し CSR する例です。 Navigation Prev Page
  87. CSR (Each Request) Edge / Origin API Server/DB Component マウントを

    hook にした fetch の場合、 Navigation Prev Page
  88. Edge / Origin API Server/DB Navigation ごとに ...loading 表示が発生するため、体験がよくありません。 Navigation

    Prev Page CSR (Each Request)
  89. SWR (No Cache) Edge / Origin API Server/DB In-Memory SWR

    を利用したデータ取得を見ていきます。Cache はまだ有りません。 Navigation Prev Page
  90. SWR (No Cache) Edge / Origin API Server/DB In-Memory SWR

    で Component マウントと同時にデータを取得した場合、 Navigation Prev Page
  91. SWR (No Cache) Edge / Origin API Server/DB In-Memory 取得したデータを

    Memory (ブラウザ) に Cache します。 Navigation Prev Page Cache
  92. SWR (With Cache) Edge / Origin API Server/DB In-Memory この

    Cache がある場合、データが即座に返るので ...loading は表示されません。 Navigation Prev Page
  93. SWR (With Cache) Edge / Origin API Server/DB In-Memory データは古くなっている可能性があるため、裏側で再取得を試みます。

    Navigation Prev Page
  94. SWR (With Cache) Edge / Origin API Server/DB In-Memory 再取得したデータに差分があった場合、再描画が走ります。

    Re-Render Navigation Prev Page
  95. SWR (With Cache) Edge / Origin API Server/DB In-Memory 取得したデータは新しい

    Cache として、次回活用されます。 Re-Render Navigation Prev Page Cache
  96. Edge / Origin API Server/DB In-Memory Cache を保持した状態で Navigation すると、視覚的に安定します。

    Navigation Prev Page SWR (Programmatically Prefetch)
  97. SWR (Programmatically Prefetch) Edge / Origin API Server/DB In-Memory そこで、Navigation

    前にデータを取得してしまうのが Prefetch です。 Navigation Prev Page Cache
  98. SWR (Programmatically Prefetch) Edge / Origin API Server/DB In-Memory mutate

    を先行して実行すると、あらかじめ取得したデータを Cache できます。 Navigation Prev Page Cache ※ Programmatically Prefetch:https://swr.vercel.app/docs/prefetching#programmatically-prefetch
  99. next/link (Prefetch) Navigation Prev Page Cache API Server/DB next/link による

    Prefetch は、SWR による Prefetch と同等の効果があります。 In-Memory Edge / Origin ※ Route prefetching in Next.js: https://web.dev/route-prefetching-in-nextjs/
  100. next/link (Prefetch) Prev Page API Server/DB next/link はリンク先ページに getStaticProps が定義されている場合、

    In-Memory Edge / Origin
  101. Prev Page Cache API Server/DB マウスオーバー等をトリガーに、遷移先の getStaticProps を実行します。 next/link (Prefetch)

    In-Memory Edge / Origin
  102. Prefetch は高速な Navigation を実現し、視覚的安定性に貢献します。 Navigation Prev Page Cache API Server/DB

    next/link (Prefetch) In-Memory Edge / Origin
  103. SWR (Programmatically Prefetch) Edge / Origin API Server/DB In-Memory SWR

    の Cache Prefetch は、パーソナライズドデータも扱えます。 Navigation Prev Page Cache
  104. Next.js x Granular Prefetch いずれの Prefetch も視覚的安定性に有用です。 しかし「表示されるであろう予測」にもとづくデータ取得は、 無駄になってしまう事もあります。 next/link

    は大味な Prefetch がデフォルトなので、注意が必要です。 【参考】Link と ISR が引き起こす Next.js の過負荷 https://zenn.dev/takepepe/articles/nextjs-isr-prefetch
  105. Next.js x Granular Prefetch SWR では Prefetch を行う Component は提供されていません。

    next/link と同じように振る舞う Component を用意すれば、 遷移後の ...loading 表示を限りなく抑えられるでしょう。 過度の Prefetch とならないよう、バランスを取ることが肝心です。
  106. Next.js x Granular Prefetch 【Next.js には不向きですが余談】 まさにこの Client Side の

    Cache Prefetch 機構を実現したのが 「React Location」です。 React Query 作者の Tanner 氏が router ライブラリとして先日発表。 routing と prefetching のインテグレーションを提供しています。 【参考】React Location https://react-location.tanstack.com/
  107. Next.js x Granular Chunk

  108. SPA Chunk Problems Next.js の様なフレームワークがなかったころ、 SPA は単一の chunk に結合されてしまうなど、 適切に

    chunk 分割されているとは限りませんでした。 chunk 分割はやや敷居が高く、 誰もが無意識にできていた事ではありませんでした。
  109. SPA Chunk Problems chunk ファイルが適切に分割されていないと、 「ファイルのロード・解析・実行」というApp 起動に、 多くの時間を有することを意味します。 どういうことなのか、簡単な概念図でみていきます。

  110. SPA Chunk Problems 最初のページを、80KB でスタートしたとします。 80 KB Page Bytes Page

    Sources Common Sources Single Chunk
  111. SPA Chunk Problems 2ページ追加したことで、Chunk が 50 KB 増加しました。 Single Chunk

    130 KB + 50 KB Page Bytes Page Sources Common Sources 130 KB 130 KB
  112. SPA Chunk Problems 最初のページは変更が無いにもかかわらず、50 KB 増加しています。 Single Chunk 130 KB

    + 50 KB Page Bytes Page Sources Common Sources 130 KB 130 KB
  113. SPA Chunk Problems ページが増えていくごとに、全ページの立ち上がり速度が低下します。 Single Chunk 180 KB + 100

    KB Page Bytes Common Sources Page Sources 180 KB + 50 KB 180 KB 180 KB + 50 KB 180 KB
  114. Chunk Per Page 従来 SPA においては、この課題が顕著でした。 Next.js では「ページ単位」で chunk が分割されるため、

    自然と必要最小限のコードのみが、 立ち上げ時にロードされる様になります。
  115. Chunk Per Page 最初の1ページは同様に、80KB でスタート。 Page Chunk 80 KB Page

    Bytes Page Sources Common Sources
  116. Chunk Per Page 最初のページに関係ない Source は、該当ページの Chunk には含まれません。 Page Chunk

    80 KB Page Bytes Page Sources Common Sources 50 KB 60 KB
  117. Chunk Per Page ページが増えても、影響のないページの立ち上がり速度は低下しません。 Page Chunk 80 KB Page Bytes

    Page Sources Common Sources 50 KB 60 KB 60 KB 50 KB
  118. Chunk Per Page 不要な初期スクリプトの読み込みは、TBT・TTI に影響します。 ページ単位の chunk 分割は、Next.js で開発する十分な動機になります。 chunk

    肥大化を意識することなく、 必要な機能を追加し続けることができます。
  119. Chunk Per Page ページ単位の chunk 分割のほか、 Google Chrome チーム (現

    Aurora チーム) の協力のもと、 部分的に共通している実装を効率的に chunk 分割する 「granular chunking」が導入されたことも話題になりました。 【詳細】Improved Next.js and Gatsby page load performance with granular chunking https://web.dev/granular-chunking-nextjs/
  120. Common Sources Problems しかし、フレームワークの用意したソリューションにも限界はあります。 共通ソースファイルは設計次第で「太り」やすくなります。 お手元の _app chunk サイズがどの様に肥大化していったか、 コミットを遡って調べてみてください。

    本当に App 起動時に必要なコードに絞られているでしょうか?
  121. 特定のページに 20 KB ぶんの実装を追加をする必要が出たとします。 Page Chunk 80 KB Page Bytes

    Page Sources Common Sources 50 KB 60 KB 60 KB 50 KB Common Sources Problems
  122. 本来は必要なページでのみ、20 KB 増加としたいです。 Page Chunk 80 KB Page Bytes Page

    Sources Common Sources 50 KB 80 KB + 20 KB 60 KB 50 KB + 20 KB Common Sources Problems
  123. しかし設計都合で _app に実装を追加するしかなく、共通 Sources が肥大化。 Page Chunk 100 KB +

    20 KB Page Bytes Page Sources Common Sources 70 KB + 20 KB 80 KB + 20 KB 80 KB + 20 KB 70 KB + 20 KB + 20 KB _app.tsx Common Sources Problems
  124. 全てのページで 20 KB の増加が余儀なくされました。 Page Chunk 100 KB + 20

    KB Page Bytes Page Sources Common Sources 70 KB + 20 KB 80 KB + 20 KB 80 KB + 20 KB 70 KB + 20 KB + 20 KB _app.tsx Common Sources Problems
  125. 状態管理の実装であったり、Global UI の実装次第では、 この肥大に伴う「起動初速の低下」は不可避かもしれません。 有名どころで言うと、Redux の Reducer は不可避ですし、 React.Context Provider

    を _app に置いた場合も、この状態となります。 granular chunking をもってしても、この問題が混入します。 Common Sources Problems
  126. また、型安全のために自動生成した fetch client でも 不要な実装を含めてしまう懸念があります。 aspida は `outputEachDir: true` を指定しなければこの状態になりますし、

    graphql-codegen でも以下参考記事のように分割指定をするべきです。 OpenAPI から型定義のみ出力する、というのも良いでしょう。 Common Sources Problems 【参考】next.jsでのファイルチャンク最適化の一例 https://blog.hiroppy.me/entry/2021/08/12/092839
  127. 以下の観点で、設計初期から共通 Sources 肥大化に気をつけましょう。 ▪ chunk 分割しやすい状態管理ライブラリを使っているか ▪ 自動生成される fetch client

    等は、ユースケース単位で分割できているか ▪ Context Provider の適用範囲は、ページ単位に閉じることはできないか ▪ _app に実装を追加する場合、将来どの様に肥大化するか想定しておく Common Sources Problems
  128. Conclusion

  129. Conclusion 近年 Aurora チームの密接な連携により、 Next.js を使用したサイトの 91% 以上が 優れた Core

    Web Vitals を獲得したそうです。 誰もが最適化の恩恵を受けている証です。 ※ 引用:https://twitter.com/hdjirdeh/status/1457679313965240325
  130. Conclusion 【詳細】Performance as a default with Next.js https://web.dev/performance-as-a-default-with-nextjs/ これまでの取り組みの内容は web.dev

    に寄稿があります。 Next.js に搭載された機能とあわせて、 パフォーマンスにどう向き合うべきか 調べてみましょう。 ※ 引用:https://twitter.com/hdjirdeh/status/1457679327630266369
  131. Conclusion 今日紹介したように、より良いパフォーマンスを追求するためには、 工夫を凝らしたり・注意しなければいけない事もあります。 新しい機能が出たからといって、その機能が 全てのサイトにとって最適解ではないこともあります。 計測し、自分たちにとって最適なものを選んでいきましょう。

  132. より速い Web を目指しましょう!! ー ご清聴ありがとうございました ー