Open4

【Tips】Next.js Pages Router と Web Vitals

ほこりぽんほこりぽん

TTFB(Time To First Byte)

サーバー初期応答時間(HTMLの最初の1byte受信)

FCP(First Contentful Paint)

視覚コンテンツの初期表示時間

なんでもよいのでUIが表示されるまでの時間

LCP(Largest Contentful Paint)

最大視覚コンテンツの表示時間

画面の大きなコンテンツが表示されるまでの時間

※以下はLCPがfetchによって作られる場合の話
CSRの場合はfetchが挟まるので、FCPよりLCPが遅くなる
SSGやISR(Incremental Static Regeneration)の場合はFCPが静的で変化されるのでFCPとLCPが同じ時間になることがある

ほこりぽんほこりぽん

レンダリングの種類

SSG

  1. req
  2. CDN配信(キャッシュされていた場合、されていない場合の動きは後述する)
  3. HTMLを受信(TTFBの計測がされる)
  4. HTMLをパース
  5. 画面が表示(FCPとLCPの計測)
  6. JavaScriptの読み込み
  7. ハイドレーション
  8. インタラクティブになる

・TTFBが高い(CDNから速攻レスポンスがあることが理由)
・FCP、LCPが早い(HTMLがパースされたタイミングLCとFCが生成されることが理由)

※フォールバック属性を設定することでDynamic RoutesのときのMISSのリクエスト時のレスポンス内容を変更させることができる。

SSR

リクエストの度に以下が毎回実行され新しいHTMLがレスポンスされる(サーバーレスファンクションが毎回実行される)

  1. req
  2. サーバーへ到達(serverSideProps)
  3. AWSラムダでfetch+レンダリングがされる(vercelサーバーへのデプロイした場合)
  4. HTMLができたらレスポンス
  5. HTMLを受信
  6. HTMLをパース
  7. 画面が表示
  8. JavaScriptの読み込み
  9. ハイドレーション
  10. インタラクティブになる

・fetchが長いとTTFBが長くなる(4が長くなるため画面が表示されない時間が長くなる)
・FCP、LCPが早い(HTMLがパースされたタイミングLCとFCが生成されることが理由)
・エッジサーバーにキャッシュされない

SSG + CSF(client side fetch)

  1. req
  2. 空のHTMLをレスポンス
  3. HTMLを受信
  4. HTMLをパース
  5. 画面が表示(FCPを計測)
  6. JavaScriptの読み込み
  7. ハイドレーション
  8. CSF
  9. レスポンス取得
  10. レスポンスを使ってメインコンテンツの表示(LCPを計測)

・TTFBが高速(キャッシュされるのは空のHTMLになる)

ISR

動的なデータを扱えるSSGみたいなやつ。
revalidate属性で設定した時間経過しているときに「ダイレクトにアクセス」もしくはLinkコンポーネントの「pre-fetch」が実行されるとISRが動く。動くとHTMLの再生成が行われる(re build)。
ただし、1回目のアクセスでは古いHTMLを返却するので、再生成されたHTMLを見れるのは2回目のアクセスしたクライアント。

On-demand ISR

ISRは「pre-fetch」によって無駄ない再生成が頻繁に発生してしまう。
On-demand ISRは、fetchするデータに更新があったときだけ再生成するようになっており、最新のデータを常に届けられるSSGみたいなやつ。

ほこりぽんほこりぽん

Vercel Edge Network(エッジサーバー・Edge CDN)

・vercelは世界16か所にエッジサーバーを配置している。
・デプロイ後31日間キャッシュされる
・デプロイするとそれまでのキャッシュは無効になる

  1. デプロイ(vercelのOrigin serverに配置される)
  2. アクセス時にエッジサーバーにリクエストがとぶ
  3. Edge Cacheにキャッシュがなければx-vercel-cacheと呼ばれるヘッダーにMISSという状態になる
  4. キャッシュにHITしなかった場合はOrigin serverに取りに行く
  5. 取得結果をエッジサーバーにセットする
  6. 2回目以降は「x-vercel-cache:HIT」となりエッジサーバーから配信されるので高速(TTFBが高速)
    ※5では別の国のエッジサーバーには配置されていないので注意
ほこりぽんほこりぽん

エッジサーバーでキャッシュされるもの

SSG

①SSG側でのfetchなし(静的ファイル)

・HTML

②fetchあり(getStaticPaths + getStaticProps=DynamicルートSSG)

・HTML
・fetch結果のjson

③SSG側でのfetchなし + CSF

・HTML
・CSF結果のjson

④fetchあり + CSF

・HTML
・CSF結果のjson

ISR(getStaticProps + revalidateの設定)

⑤ISRだけ

・HTML
・fetch結果のjson

⑥ISR+CSF

・HTML
・fetch結果のjson

SSR

⑦SSR

なし

jsonファイルの使い道

画面を作るために使う

前提として
ページを表示するのに必要なものは

  1. HTML(UI)
  2. JS(ハイドレーションに使用する)
  3. fetchしたデータ(json)

この3つはedge cacheにある

ではjsonファイルはいつ使用されるのかというと
例えば、CSRのページからSSGのページへ遷移する場合
遷移先で必要なJSをキャッシュからロードしてレンダリングする
このとき、レンダリングする際に必要なfetchデータもキャッシュから取得する

このようにfetchをしないで画面を作成するのにつかわれる。