RE: 光を超えるためのフロントエンドアーキテクチャ

@mizchi

Hack@DELTA 「わたし史上、最高のチューニング」 2024/10/29

About

最近やったチューニング

はじめに

  • mizchi「マジで資料作成時間がないので、2018年のスライドとその+αでいい?」
  • 西谷さん「いいよ」

会場はたぶんサーバーサイドの人が多い?

フロントエンド視点の マクロ寄りで キャッシュの話をします

用語

  • WebVitals: Google のウェブサイトのスピード指標
    • FCP: First Contentful Paint
      • 最初のコンテンツの描画タイミング = 初期HTML(DOM)
    • LCP: Largest Contentful Paint
      • ページ内の最も大きな要素の確定タイミング = CSS/JS 適用後
  • Core WebVitals
    • SEOに関与するWebVitalsのスコア。FCP/LCP/CLS/TBT

2018: 光を超えるためのフロントエンドアーキテクチャ

https://speakerdeck.com/mizchi/guang-wochao-erutamefalsehurontoendoakitekutiya

(身も蓋もない)結論

  • CDNで静的HTMLを返したい
  • 遷移先を投機的プレロード
  • 弱整合/強整合は 「納得感」をハックする技術
  • (それができたら苦労はしねえ)

2018年と2024年の違い

  • フロントエンド: 初期ロードが重いSPA技術 -> パフォーマンス技術
  • CDN Edge Worker 周辺が枯れてきた
  • Core WebVitals で(強制的に)非機能要件に投資する動機が生まれた

フロントエンドのマクロなパフォーマンス設計

2024年のフロントエンド的ゴール設定

  • 仮の定数
    • to CDN: 10~30ms (※転送量依存)
    • to Origin: 30~100ms (※日本国内)
    • DB Query: 150~1000ms (※SQL依存)
    • VPC内の接続: 3~5ms
  • LCP で100点出せる 2500ms 以内を達成したい
    • フロントエンド側のロード開始からコンテンツ確定までのバッファは 約1000ms ぐらいとしておく
    • HTML/JS/CSS のロード/パースに 200ms はかかる
    • 1リクエストを仮に 300ms とすると、許されるラウンドトリップは 2~3RTT

フロントエンドのチューニング時に考えること

  • 誰にとってのパフォーマンスか?
    • ユーザー: UX
    • Google: SEOスコアの減点・加点
    • 開発者: 手動テスト確認/E2Eテスト高速化
  • メディア系(ブログやニュース等)
    • キャッシュなしの初回ロード(LCP)を速くしたい
  • 管理画面・ツール系
    • 初回ロード後のインタラクションや遷移(INP)
    • (多様なので、今回は扱わない)
full
full

キャッシュヒットの考え方

  • 「コンテンツはいつ誰が確定させるのか?」
  • 可能な限り静的アセットをCDNに当てにいく

VS ウォーターフォール

  • LCP を確定するのに、リクエスト間に依存がある回数
  • 画面表示に関与した一番最後のリクエストから逆算する
  • アプリケーションロジックであることが多い

VS 並列リクエスト

  • 並列に飛んでる分にはあまり気にしなくていい
  • 最大同時リクエスト制限(目安PC:16,モバイル8)制限があるので Math.floor(リクエスト数/最大並列数) で実質的に +N RTT
  • サードパーティはウォーターフォールになりにくいが、同時リクエスト数に割り込んでる

パターンごとの比較検討

Static HTML on CDN

  • CDNエッジから静的アセットをそのまま返却
  • 最速だが柔軟性はない
  • 阿部寛AMP

(古典的) MPA

  • リクエストのたびにサーバー越しにDBからデータを取得
  • CGI からの伝統的なアーキテクチャ

Modern MPA with API

  • 古典的MPAの発展型
  • 非同期APIで遅延解決+静的アセットをCDNに配置
  • 2015年ぐらいのベストプラクティス
  • たぶん一番多い形

MPA with Cache Proxy

  • MPAの一部に CDN Cache を被せるパターン
  • うまく設計すると既存の設計のままメジャーシナリオを高速化できる
  • 日経メルカリ 等のメディアに多い

Edge Worker as Front

  • フロントサーバーをCDN Edge Worker に置くパターン
  • 動的エッジキャッシュ
  • Remix(on Cloudflare), Next(on Vercel) が裏側でやってること

結局何がやりたいんだっけ?

  • LCP 確定までを Edge Cache だけでやりたい
  • 部分的に静的サイトとして扱いたい
    • SSR => アイランドアーキテクチャ
  • そのためにフロントエンドは エッジキャッシュを柔軟に扱いたい
    • キャッシュをアプリケーションロジックで扱う
    • キャッシュパージはとにかく高速であってほしい!!!!
  • キャッシュ管理はフレームワークに任せたい
    • Next/Remix の SSR/RSC の裏側に押し込みたい
    • 難しいので…

おわり

時間が余ったら GraphQL BatchでクライアントN+1を無理矢理倒す