レスポンスの遅延を80%削減した方法

Subitoはイタリアのトップマーケットプレイスです。私たちは毎分数千件のリクエストを処理しています。広告詳細ページは、SEOと収益にとって極めて重要です。

このページをNext.jsのPages RouterからApp Routerへ移行しました。移行のためにプロダクト開発を止めることはせず、小さなステップを踏んで進めました。

その手法を以下に紹介します。

アプローチ

私たちはインクリメンタル(段階的)な戦略を採用しました。従来のPages Routerと並行してApp Routerのツリーを追加しました。これにより、移行を進めながら新しい機能をリリースすることができました。

データフェッチを管理するためにServer Componentsを使用しました。これにより、多くのレイヤーを経由してデータを渡す必要がなくなりました。また、Data Access Layerも作成しました。これにより、1回のリクエストにつきデータの取得が1回のみであることを保証しました。

HTMLストリーミングを有効にするために、Suspenseとuse()フックを使用しました。これにより、データ読み込み中にスケルトンスクリーンが表示されるようになり、ユーザーはより早くページを確認できるようになりました。

課題

問題1: HTTP 410 Gone 検索エンジンは、ページが恒久的に削除された際に410ステータスを必要とします。App Routerには、これを送信する組み込みの方法がありません。私たちはExpressサーバーを使用してこれを解決しました。サーバーがレスポンスをインターセプトし、ステータスコードを変更するようにしました。

問題2: HTMLストリーミング ローディング用のスケルトンが表示されないことが分かりました。ページが数秒間空白のままになってしまったのです。

NginxとAkamaiがレスポンスをバッファリングしていることが判明しました。CDNがHTMLをバッファリングしてしまうと、ストリーミングは失敗します。Nginxのバッファリングをオフにし、Akamaiにカスタム設定を適用する必要がありました。これを修正したことで、コンテンツはユーザーに完璧にストリーミングされるようになりました。

ロールアウト

SEOを守るために、2つのフェーズに分けてロールアウトしました。

フェーズ1: トラフィックをApp Routerに移行しましたが、ストリーミングはオフのままにしました。これをカテゴリーごとに一つずつ実施しました。

フェーズ2: HTMLストリーミングを有効にしました。まずは小規模なカテゴリーでテストを行いました。次のカテゴリーへ移行する前に、SEOチームが2週間にわたってランキングをモニタリングしました。

結果

結果は絶大でした。移行前は、レスポンスの最大40%が低速でした。移行後、低速なレスポンスは80%減少しました。

現在、ほとんどのページが500ms未満でロードされます。

教訓

Next.js App Routerへの移行により、低速なレスポンスを80%削減した方法

高性能なeコマースプラットフォームを構築する道のりにおいて、私たちは大きなボトルネックに直面しました。それは、レスポンスの遅延です。

具体的には、TTFB(Time to First Byte)が高く、ユーザーは遅延を経験していました。

Pages Routerは強力なフレームワークですが、いくつかの制限がありました。主な問題は以下の通りです:

そこで、私たちはNext.js App Routerへの移行を決定しました。

なぜApp Routerが効果的だったのか

1. React Server Components (RSC)

RSCを活用することで、データフェッチの大部分をサーバー側で行うことができました。これにより、クライアントに送信されるJavaScriptの量を劇的に減らすことができ、Hydrationのコストも大幅に軽減されました。

2. Streaming と Suspense

Suspense を使用して、ページ全体が読み込まれるのを待つのではなく、準備ができたコンポーネントから順次ストリーミングして表示を開始できるようになりました。これにより、ユーザーはページの主要な部分をより早く目にすることができ、体感的な待ち時間が大幅に短縮されました。

3. データフェッチの改善

App Routerの拡張されたfetch APIにより、サーバー側でのキャッシュとリクエストの重複排除(deduplication)が容易になりました。これにより、同じデータを複数のコンポーネントで必要としても、ネットワークリクエストは一度だけで済みます。

結果

この移行により、パフォーマンスは劇的に改善されました。

Next.js App Routerへの移行は、単なる技術的なアップグレードではなく、ユーザー体験を根本から改善するための戦略的な決定でした。