ジャムジャム!!Jamstack_2に登壇した際の発表資料です。 https://jamjamjamstack.connpass.com/event/226467/
ご質問あれば、Twitter: aiji42_dev までどうぞ。
0ジャムジャム!!Jamstack_270万通りのURLを持つWebサービスをNext.jsにリプレイスして⾼速化した話
View Slide
1© 2021 Ateam Inc. 1Uejima Aijiリードエンジニア@株式会社エイチームライフスタイルTwitter: aiji42_dev8年のキャリアの中で、フロントエンジニアよりもバックエンドエンジニアとしてのキャリアのほうが長い (3:7くらい)でも最近はフロントエンドがメイン
2© 2021 Ateam Inc. 2今日はURLが膨大なサービスにNext.jsを導入した際の
3© 2021 Ateam Inc. 3立ちはだかった壁とその乗り越え方を紹介します
4© 2021 Ateam Inc. 4題材となるサービス
5© 2021 Ateam Inc. 5ライフエンディングに関する情報サイト自分や家族にぴったりのお墓・霊園を探し、資料請求をするサービス
6© 2021 Ateam Inc. 6トップ 記事 霊園詳細1K Pages 700K Pages 30K Pagesエントリー霊園リスト&検索
7© 2021 Ateam Inc. 7トップ 記事 霊園リスト&検索 霊園詳細1K Pages 700K Pages 30K Pagesエントリーエリア(市区町村・駅)x霊園特徴(樹木葬, 納骨堂...etc.)
8© 2021 Ateam Inc. 8もともとはパフォーマンスが非常に悪かった
9© 2021 Ateam Inc. 9引用: https://addyosmani.com/blog/web-vitals-extension/
10© 2021 Ateam Inc. 10LCP (Largest Contentful Paint)CLS (Cumulative Layout Shift)
11© 2021 Ateam Inc. 112020年CoreWebVitalsをSEO評価に導入するとのアナウンスがあったhttps://developers.google.com/search/blog/2020/11/timing-for-page-experience
12© 2021 Ateam Inc. 12手を打つ必要があるということで
13© 2021 Ateam Inc. 13Next.jsを用いたJamstack化によるCoreWebVitalsの改善を行った
14© 2021 Ateam Inc. 14その結果大幅なパフォーマンス改善に成功!
15© 2021 Ateam Inc. 15LCP CLS
16© 2021 Ateam Inc. 16本題に入る前に
17© 2021 Ateam Inc. 17SSR / SG / ISR
18© 2021 Ateam Inc. 18この3つの用語を居酒屋を例にしておさらい
19© 2021 Ateam Inc. 19SSR (Server Side Rendering)
20© 2021 Ateam Inc. 20注文を受けて、その都度ドリンクを注いで提供
21© 2021 Ateam Inc. 21時間はかかるがキンキンに冷えている(リアルタイム志向)
22© 2021 Ateam Inc. 22SG (Static Generate)(少し前まで SSG と呼ばれていた)
23© 2021 Ateam Inc. 23開店前にドリンクを作り置きしておく
24© 2021 Ateam Inc. 24提供は爆速しかし鮮度は保証できない※注文が入ってもストックの数は減らない
25© 2021 Ateam Inc. 25ISR (Incremental Static Regenerate)
26© 2021 Ateam Inc. 26作り置きするのはSGと同じドリンクを提供した際に鮮度が落ちていたら次の注文に備えて作り直す
27© 2021 Ateam Inc. 27提供は爆速注文頻度の高いメニューは鮮度良
28© 2021 Ateam Inc. 28今日お話するライフドットではISRを採用していますそしてVercelにデプロイしています
29© 2021 Ateam Inc. 29前提知識のインストールができたところで本題
30© 2021 Ateam Inc. 3070万通りのURLを持つサービスをNext.jsに導入する際の一番大きな壁
31© 2021 Ateam Inc. 31デプロイ時間
32© 2021 Ateam Inc. 3270万通りのページを生成するのにどれだけ時間がかかるか?
33© 2021 Ateam Inc. 331ページ生成100msと仮定しても
34© 2021 Ateam Inc. 34約19時間半
35© 2021 Ateam Inc. 35デプロイで1日が終わってしまう
36© 2021 Ateam Inc. 36先程の居酒屋の例で解決策を探る
37© 2021 Ateam Inc. 37メニューが多い居酒屋はどうしているのか?
38© 2021 Ateam Inc. 38人気メニューや手間のかかるメニューは作り置き(仕込みを)して
39© 2021 Ateam Inc. 39それ以外のメニューは注文を受けてから作っている
40© 2021 Ateam Inc. 40実際のサービスに当てはめると
41© 2021 Ateam Inc. 41PV上位コンテンツをデプロイ時に生成し
42© 2021 Ateam Inc. 42それ以外はリクエストのタイミングで生成して以降のリクエストはキャッシュを返却する
43© 2021 Ateam Inc. 43ということができればデプロイ時間を短縮できるしパフォーマンスも問題なさそう
44© 2021 Ateam Inc. 44ではNext.jsにおいてビルドするターゲットは何で決まるのか
45© 2021 Ateam Inc. 45getStaticPaths: SG/ISRのデプロイ時のビルドターゲット(パス)を決定する関数返り値に fallback: true(or "blocking") を指定すると、ビルドターゲットにないパスでリクエストを受けた際にビルドを行う。(遅延ビルド)
46© 2021 Ateam Inc. 46getStaticPathsの設定で3種類のデプロイパータンを作ることができる
47© 2021 Ateam Inc. 47フルデプロイビルドパターン 全ページをデプロイ時にビルド• 全ページ一定のアクセス量があるページ群に有効• BFFと通信してコンテンツを生成する場合、最大でも4桁程度のページ数が現実的フルデプロイビルドパターン[slag].tsxPV多PV少
48© 2021 Ateam Inc. 48フルリクエストビルドパターン デプロイ時のビルドを全スキップし、リクエスト時にビルド• デプロイは高速 <> 初アクセスはコンテンツを生成する分、多少TTFBが遅くなる• URLパターンがかけ合わせ等で指数関数的に増加するページ群に有効フルリクエストビルドパターンproduct/[id]/sub.tsxPV多PV少
49© 2021 Ateam Inc. 49ハイブリッドビルドパターン 一部のページをデプロイ時、それ以外をリクエスト時にビルド• アクセス数に偏りがあるページ群で強い効果を発揮 (例: 主要都市と地方)• デプロイ時間と相談しながらビルド対象数を選択するデプロイビルド リクエストビルドsearch/[prefecture]/[city]/[condition].tsxPV多PV少
50© 2021 Ateam Inc. 50この3種類を適切に設定し
51© 2021 Ateam Inc. 51ライフドットでは全PVにおける6~7割が初回アクセスでもビルド済みURLに到達できるようにした(※PVの分散は均一ではないことに注意)
52© 2021 Ateam Inc. 52記事 霊園リスト&検索 霊園詳細フルデプロイビルド ハイブリッドビルド(単一条件)+フルリクエストビルド(掛合わせ条件)ハイブリッドビルド(メインページ)+フルリクエストビルド(サブページ)
53© 2021 Ateam Inc. 53デプロイに要する時間はこうなった
54© 2021 Ateam Inc. 54記事 霊園リスト&検索 霊園詳細フルデプロイビルド ハイブリッドビルド(単一条件)+フルリクエストビルド(掛合わせ条件)ハイブリッドビルド(メインページ)+フルリクエストビルド(サブページ)45分
55© 2021 Ateam Inc. 55しかし
56© 2021 Ateam Inc. 56Vercel(チームプラン)のパイプラインのタイムアウトは45分
57© 2021 Ateam Inc. 5745分の間にビルドだけでなくエッジへの配備まで完了させなければならない
58© 2021 Ateam Inc. 58ビルド時間の長さに比例してエラーの発生確率も上がるデプロイ終盤のエラー発生は辛いので15分くらいでデプロイが完了できればなあ。。。
59© 2021 Ateam Inc. 59ならばさらにデプロイ時間を短縮!
60© 2021 Ateam Inc. 60さっきの居酒屋の例に話を戻そう
61© 2021 Ateam Inc. 61
62© 2021 Ateam Inc. 62
63© 2021 Ateam Inc. 63目的別でサービスを縦割りしそれぞれのデプロイを独立して行うことで時間短縮
64© 2021 Ateam Inc. 64www.lifedot.jpVercel・・・・・・
65© 2021 Ateam Inc. 65product.vercel.lifedot.jpsearch.vercel.lifedot.jp article.vercel.lifedot.jp目的別でサービスを縦割り
66© 2021 Ateam Inc. 66www.lifedot.jp/db/*//pref-*/city-*/*//pref-*/st-*/*//pref-*/cond-*/*//ohaka/[a-z]+/product.vercel.lifedot.jparticle.vercel.lifedot.jpsearch.vercel.lifedot.jpCDN(CloudFront)+エッジコンピューティング(LambdaEdge)で統合
67© 2021 Ateam Inc. 67この構成でTTFBは50ms~100ms強※通信環境によって多少異なる※それぞれ計測しているページは別(無作為に選別)
68© 2021 Ateam Inc. 68十分な速度が出ている(Googleは200msを下回ること推奨している)
69© 2021 Ateam Inc. 69そして肝心なビルド時間は
70© 2021 Ateam Inc. 70記事 霊園リスト&検索 霊園詳細15分 15分 15分それぞれ並行してビルドされるので15分に短縮
71© 2021 Ateam Inc. 71🎉
72© 2021 Ateam Inc. 72そもそもどうやってサービスのコードを分割するのか?
73© 2021 Ateam Inc. 73一部分の変更で全体のデプロイが実行されるのは効率が悪い
74© 2021 Ateam Inc. 74リポジトリを分ける?共有レイアウト・コンポネントはどうする?
75© 2021 Ateam Inc. 75開発も効率化したい!
76© 2021 Ateam Inc. 76Nxでのモノレポ戦略を採用
77© 2021 Ateam Inc. 77NxとはJSベースのモノレポ用開発ツール
78© 2021 Ateam Inc. 78特徴
79© 2021 Ateam Inc. 79Storybook, Cypress, Jest, ESLintなどが標準配備されるテストを書く文化を浸透させやすいhttps://nx.dev
80© 2021 Ateam Inc. 80package.json と node_modules がリポジトリに1つなので依存パッケージのアップデートなどバージョン管理が楽※よく比較にあがる lerna などはルートと各appごとに発生する(ただし志向や用途が違うので単純比較していいものではない)
81© 2021 Ateam Inc. 81vs code や IntelliJ用の公式プラグインがありクリックでビルド&サーブしたりテスト実行できる複雑なコマンド学習をメンバーに強要しなくて良い
82© 2021 Ateam Inc. 82appsとlibsが基本構造共通モジュールはlibsに配備自動的にプロジェクト名でエイリアスされる無意識的にnpmモジュールライクな参照が可能import { Header } "@lifedot/components"import { useStockList } "@lifedot/hooks"libsappsarticlesearchproductcomponentsrelay(graphql)hooks, router, layouts, ...etc.@lifedot/components
83© 2021 Ateam Inc. 83appsarticlesearchproductproduct.vercel.lifedot.jpsearch.vercel.lifedot.jparticle.vercel.lifedot.jpVercel の "Ignored Build Step" と組み合わせることで変更が生じたappsのみデプロイできる❌❌update
84© 2021 Ateam Inc. 84各PJが独立して15分でデプロイが可能&プロジェクトを絞ってデプロイできるようになった
85© 2021 Ateam Inc. 85🎉
86© 2021 Ateam Inc. 86今日紹介したこと
87© 2021 Ateam Inc. 871. 3パターンのデプロイ方法と遅延ビルドの活用• フルデプロイビルド• フルリクエストビルド• ハイブリッドビルド2. サービスの縦割りとCDN+エッジコンピューティングによる統合3. Nxによるリポジトリのモノレポ化
88© 2021 Ateam Inc. 88今日紹介しきれなかったこと
89© 2021 Ateam Inc. 891. バンドルサイズの削減格闘記2. 効率の良いキャッシュを目指した変動 revalidate3. GraphQLによるパフォーマンス改善の話
90© 2021 Ateam Inc. 90またの機会にお話させていただきます
91© 2021 Ateam Inc. 91ご質問やもっと詳しく聞きたい方は Twitter でどうぞ!@aiji42_dev
92ITにできることを、次々と。