React SSR のパフォーマンスをベンチマークする方法

有用な SSR ベンチマークは、特定の質問に答えます。つまり、アプリケーションはリソース予算内でどの程度の正確な作業を完了できますか? 遅延とコストはどれくらいですか? 1 秒あたりのリクエスト数だけでは、説明できないことが多すぎます。

このメソッドは、バージョン、プロファイル、または React ランタイムに適用されます。 HTTP 測定をブラウザー操作から分離し、フィクスチャ ルートに適応するための k6 サンプルが含まれています。この例自体はパフォーマンス結果を確立しません。

正しい応答を定義する

代表的なルート (動的リスト、API、またはストリーミング ページ) を選択します。データ量、依存関係、認証条件を修正します。フィクスチャ ルートは、古い応答や誤って共有された応答を検出するために、一意の要求マーカーを返すことができます。

ステータス、コンテンツ タイプ、および予期される本文の値を検証します。動的 SSR の場合、レンダリングが実際に行われることを確認します。キャッシュされた静的ファイルと新しくレンダリングされたページは異なるワークロードです。

環境を比較できるようにする

コミット、アーティファクト、ノード、React、オペレーティング システム、およびコンパイラ オプションを特定します。特定のマシン上で、同じノードの実行可能ファイルとアプリケーションの依存関係を保持します。実稼働ビルドを使用し、キャッシュと圧縮設定を記録します。

従業員や代理人を含むグループ全体の予算を設定します。トポロジの説明: 直接サーバーと比較した場合、プロキシの背後にある 2 つのプロセスにはコンテキストが必要です。別の負荷生成マシンを使用し、それが飽和するかどうかを監視してください。

動的なフィクスチャ ルートを作成する

App Router テスト アプリケーションで、この内容を含む app/bench/page.jsx を作成します。マーカーはリクエストによって異なり、動的レンダリングは明示的です。この例ではほとんど機能しません。ビジネス シナリオを評価するときに、これを代表的なレンダリングに置き換えます。

比較するランタイムのソースは同じにしてください。マーカーだけではすべてのデータの分離を証明することはできません。ユーザーがシナリオに参加している場合は、別のセッションとアプリケーション固有のアサーションを追加します。

アプリ/ベンチ/page.jsx
export const dynamic = "force-dynamic";

export default async function Benchmark({ searchParams }) {
  const { id = "missing" } = await searchParams;
  return <main>Benchmark marker: {id}</main>;
}

ロード ジェネレーターに検証を追加する

この例を Bench.js として保存します。 id クエリパラメータを HTML にエコーする /bench フィクスチャ ルートが必要です。テスト アプリケーションでそのルートを作成します。 Next.js も PRNext も自動的に提供しません。 BASE_URL は、制御するテスト インスタンスをターゲットとします。

チェックしきい値は、応答が検証に失敗した場合に実行を無効にします。別のページをサイレントに測定することを避けるために、リダイレクトは無効になっています。これはクローズド同時実行の例です。サーバーの速度が低下すると、各仮想ユーザーの待機時間が長くなります。固定到着率をシミュレートするものではありません。

ベンチ.js
import http from "k6/http";
import { check } from "k6";

export const options = {
  vus: 16,
  duration: "60s",
  thresholds: { checks: ["rate==1"], http_req_failed: ["rate==0"] }
};

export default function () {
  const id = `request-${__VU}-${__ITER}`;
  const base = __ENV.BASE_URL || "http://127.0.0.1:3000";
  const response = http.get(`${base}/bench?id=${id}`, { redirects: 0 });
  check(response, {
    "status 200": r => r.status === 200,
    "HTML response": r => String(r.headers["Content-Type"]).includes("text/html"),
    "fresh marker": r => typeof r.body === "string" && r.body.includes(id)
  });
}

ウォームアップを測定ウィンドウから切り離す

k6 がインストールされている場合は、別のウォームアップを実行してから、複数の測定ウィンドウを実行します。候補の順序を変更し、各実行の出力を保持します。このコマンドは、POSIX シェル環境構文を使用します。 PowerShell で BASE_URL の割り当てを調整します。

ジェネレーターには独自のネットワークと CPU コストがあります。両方の候補のパラメータを同一に保ち、競合するサーバーのアクティビティを記録します。繰り返しウィンドウは変動性を説明するのに役立ちますが、トポロジーの偏りを除去したり、代表的でない器具を代表したりすることはありません。

Terminal
BASE_URL=http://127.0.0.1:3000 k6 run --duration 10s bench.js
BASE_URL=http://127.0.0.1:3000 k6 run --summary-export result-a.json bench.js

スループット、レイテンシ、CPU、メモリを一緒に読み取る

p95 は、サンプリングされたリクエストの 95% が完了するまでの期間です。 k6 では、http_req_duration は DNS ルックアップや初期接続の確立などのフェーズを除外します。メトリクスに速度という名前を付けるのではなく、名前を付けます。

グループ CPU の正しい応答ごとの作業を、測定されたウィンドウにわたって個別に計算します。つまり、グループの CPU デルタを検証済みの応答で割った値です。 HTTP p95 は CPU 消費ではありません。記載されている方法でグループ メモリとプロセス ツリー PSS を記録します。パフォーマンスを比較する前に、不正なコンテンツを含むウィンドウを無効にしてください。

ブラウザ体験を追加する

クライアントは HTML をすぐに受信しながら、ハイドレーションを待つことができます。ナビゲーション、戻るナビゲーション、ビジネス インタラクションを個別に測定します。カウンター、セッション、またはフォームの状態がプロセス全体を通じて正しいままであることを確認します。

VPS の比較では、サーバーの利益はブラウザのすべての測定結果の勝利にはつながりません。それらの違いを公開すると、評価がより有用になります。プロトコル、生の出力、制限事項をグラフと一緒に保管します。

2 台の VPS マシンでの SSR とナビゲーション キャンペーンを読む

出典と詳細情報

ブログに戻る