performance-budget について
Web サービスやアプリ向けに、実行可能なパフォーマンス予算を作成するスキルです。測定可能なフロントエンド・バックエンドの制約、測定方法、CI での適用、超過時の対応を定義します。
主な機能
- 01フロントエンドとバックエンドの目標
- 02ユーザージャーニーとアセットの予算
- 03測定とモニタリングの指針
- 04CI による性能チェックゲート
- 05超過レベルと対応プロセス
活用シーン
- 01重要なユーザージャーニーの上限設定
- 02CI/CD への性能チェック追加
- 03目標超過時のチーム対応の定義
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mohitagw15856/ pm-claude-skills --skill performance-budgetインストール後、Claude Code で/performance-budgetを入力して読み込まれたか確認します。
詳細
パフォーマンスバジェットスキル
Web サービスまたはアプリケーションのために、完全で実行可能なパフォーマンスバジェット文書を作成します。パフォーマンスバジェットは希望リストではありません。「許容可能なパフォーマンス」の定義と、その制約に違反した場合の責任者を明確にする、測定可能で適用可能な制約のセットです。
優れたパフォーマンスバジェットでは、目標は何か、どのように測定するか、何が調査のきっかけとなるか、予算を超過した場合にどうなるかを明らかにします。
必須入力
まだ提示されていない場合は、以下を尋ねてください。
- サービス名と種類 — Web アプリ、API サービス、モバイルアプリ、またはその組み合わせ
- 主要なユーザージャーニー — ユーザーがたどる、最も重要な3~5個のフロー(例:「検索 → 商品ページ → チェックアウト」)
- 現在のベースライン指標 — P50/P95/P99 レイテンシ、LCP、CLS、INP(利用可能な場合)(まだ収集していない場合は「ベースラインなし」と記載)
- 技術スタック — フロントエンドフレームワーク、バックエンド言語/フレームワーク、CDN、データベース
- デプロイ環境 — クラウドプロバイダー、リージョン、エッジ/CDN 構成
- コスト上の制約 — 余裕に影響する予算やインフラの制限
出力形式
パフォーマンスバジェット:[サービス名]
サービス: [名前] | チーム: [チーム名] 最終更新日: [日付] | オーナー: [名前/役割] 環境: [本番環境/ステージング環境のベースライン] | レビュー頻度: [四半期ごと/スプリントごと]
概要
[サービス、ユーザー向けのパフォーマンス要件、パフォーマンスを優先する理由を2~3文で説明します。コンバージョン率、ユーザー維持率、SLA の義務など、レイテンシがビジネスに与える影響を記載してください。]
パフォーマンスに関する方針: [例:「パフォーマンスは機能の一つです。サービスを予算内に保つ責任はすべてのエンジニアにあります。リグレッションは本番環境に到達する前に CI で検出する必要があります。」]
主要なユーザージャーニー
パフォーマンスバジェットで保護する重要な経路を定義します。
| ジャーニー ID | ジャーニー名 | 開始地点 | 終了地点 | 重要度 |
|---|---|---|---|---|
| UJ-1 | [例:新規ユーザー登録] | [ランディングページ] | [ダッシュボード] | 重大 |
| UJ-2 | [例:コアワークフローのタスク] | [例:/app/tasks] | [例:タスク完了] | 高 |
| UJ-3 | [例:検索と選択] | [例:/search] | [例:詳細ページ] | 高 |
| UJ-4 | [例:API データ取得] | [例:GET /api/items] | [例:200 レスポンス] | 中 |
フロントエンドのパフォーマンスバジェット
Web アプリケーションおよびモバイルアプリケーションでは、このセクションを記入してください。API のみのサービスでは省略してください。
Core Web Vitals の目標
特に記載がない限り、目標は実ユーザーセッション(フィールドデータ)の75パーセンタイルに適用され、4G 接続のミドルレンジ Android デバイスで測定されます。
| 指標 | 説明 | 良好 | 改善が必要 | 不良 | 目標値 | 現在のベースライン |
|---|---|---|---|---|---|---|
| LCP | Largest Contentful Paint — 体感読み込み速度 | ≤2.5s | 2.5–4.0s | >4.0s | [≤X.Xs] | [Xs/未測定] |
| INP | Interaction to Next Paint — 応答性 | ≤200ms | 200–500ms | >500ms | [≤Xms] | [Xms/未測定] |
| CLS | Cumulative Layout Shift — 視覚的な安定性 | ≤0.1 | 0.1–0.25 | >0.25 | [≤0.X] | [X.XX/未測定] |
| FCP | First Contentful Paint | ≤1.8s | 1.8–3.0s | >3.0s | [≤X.Xs] | [Xs/未測定] |
| TTFB | Time to First Byte | ≤800ms | 800ms–1.8s | >1.8s | [≤Xms] | [Xms/未測定] |
ページ容量の予算
| アセットの種類 | 最大サイズ(圧縮後) | 現在 | ステータス |
|---|---|---|---|
| ページ全体の容量 | [例:500KB] | [XKB/不明] | [範囲内/超過/不明] |
| JavaScript(初回読み込み) | [例:200KB] | [XKB/不明] | [範囲内/超過/不明] |
| CSS | [例:50KB] | [XKB/不明] | [範囲内/超過/不明] |
| 画像(ファーストビュー) | [例:150KB] | [XKB/不明] | [範囲内/超過/不明] |
| Web フォント | [例:50KB] | [XKB/不明] | [範囲内/超過/不明] |
| サードパーティスクリプト | [例:100KB] | [XKB/不明] | [範囲内/超過/不明] |
ジャーニーごとのフロントエンド目標
| ジャーニー | LCP | INP | CLS | FCP | TTFB |
|---|---|---|---|---|---|
| UJ-1:[ジャーニー名] | [≤Xs] | [≤Xms] | [≤0.X] | [≤Xs] | [≤Xms] |
| UJ-2:[ジャーニー名] | [≤Xs] | [≤Xms] | [≤0.X] | [≤Xs] | [≤Xms] |
| UJ-3:[ジャーニー名] | [≤Xs] | [≤Xms] | [≤0.X] | [≤Xs] | [≤Xms] |
バックエンドのパフォーマンス予算
API レイテンシの SLO
サービス境界で測定した目標です(クライアント側のネットワークレイテンシは含みません)。
| エンドポイント/操作 | メソッド | P50 | P95 | P99 | 最大(ハードリミット) | エラー率 |
|---|---|---|---|---|---|---|
| [例:/api/auth/login] | POST | [≤Xms] | [≤Xms] | [≤Xms] | [≤Xms] | [<X%] |
| [例:/api/items] | GET | [≤Xms] | [≤Xms] | [≤Xms] | [≤Xms] | [<X%] |
| [例:/api/items/:id] | GET | [≤Xms] | [≤Xms] | [≤Xms] | [≤Xms] | [<X%] |
| [例:/api/items] | POST | [≤Xms] | [≤Xms] | [≤Xms] | [≤Xms] | [<X%] |
| [例:バックグラウンドジョブ:同期] | — | [≤Xs] | [≤Xs] | [≤Xs] | [≤Xs] | [<X%] |
サービス全体の SLO:
| SLO | 目標 | 測定期間 |
|---|---|---|
| 可用性 | [99.X%] | 過去30日間のローリング |
| P95 レイテンシ(全エンドポイント) | [≤Xms] | 過去30日間のローリング |
| エラー率(5xx) | [<X%] | 過去30日間のローリング |
| スループット(持続) | [≥X req/s] | ピーク時間 |
データベースクエリの予算
| クエリ/操作 | P50 | P95 | 最大 | 備考 |
|---|---|---|---|---|
| [例:ID によるユーザー検索] | [≤Xms] | [≤Xms] | [≤Xms] | user_id にインデックス |
| [例:ユーザーのアイテム一覧] | [≤Xms] | [≤Xms] | [≤Xms] | ページネーションあり、最大100行 |
| [例:全文検索] | [≤Xms] | [≤Xms] | [≤Xms] | Elasticsearch / pg_trgm |
測定方法
リアルユーザーモニタリング(RUM)
ツール:[例:Google CrUX、SpeedCurve、Datadog RUM、Sentry Performance、カスタム]
データソース:[実ユーザーのフィールドデータ/合成テストのラボデータ/両方]
サンプルレート:[セッションのX%]
アクセス方法:[ダッシュボードの URL またはツールへのアクセス手順]
測定項目:
- ページおよびジャーニーごとの Core Web Vitals(LCP、INP、CLS)
- ビジネス上重要なインタラクションのカスタムパフォーマンスマーク
- 主要アセットのリソースタイミング
- ロングタスク(メインスレッド上で50ms超)
合成モニタリング
ツール:[例:Lighthouse CI、WebPageTest、k6、Artillery、パフォーマンスアサーション付き Playwright]
頻度:[X分ごと/デプロイのたび/毎晩]
テスト場所:[例:eu-west-1、us-east-1]
デバイスプロファイル:[デスクトップ 10Mbps/モバイル 4G Moto G4/両方]
合成テストスイートの場所:[テストファイルへのリンク]
バックエンドのオブザーバビリティ
APM ツール:[例:Datadog、Grafana + Prometheus、New Relic、AWS X-Ray]
収集するメトリクス:
- エンドポイントごとのリクエスト率、エラー率、処理時間(RED メトリクス)
- データベースクエリの処理時間と接続プールの使用率
- キャッシュのヒット率/ミス率
- バックグラウンドジョブのキュー深度と処理レイテンシ
ダッシュボード:[主要なパフォーマンスダッシュボードへのリンク]
CI/CD によるパフォーマンスの適用
パフォーマンス予算は、次の2つのゲートで適用されます。
ゲート 1 — ビルド時のバンドル分析
ツール:[例:bundlesize、size-limit、CI アサーション付き webpack-bundle-analyzer]
設定ファイル:[[.bundlesizerc / .size-limit.js / etc.]]
トリガー:main を対象とするすべての PR
**ブロック:**はい — バンドルサイズが予算を超過した場合、PR はマージできません
// Example .size-limit.js
[
{
"path": "dist/js/*.js",
"limit": "200 KB"
},
{
"path": "dist/css/*.css",
"limit": "50 KB"
}
]
ゲート 2 — CI での合成パフォーマンステスト
ツール:[例:Lighthouse CI、k6、Artillery]
**トリガー:**ステージングへのデプロイ時
**ブロック:**はい — しきい値を満たさない場合、本番環境へのデプロイはブロックされます
確認するしきい値:
- LCP ≤ [Xs]
- CLS ≤ [0.X]
- API レイテンシの P95 ≤ [Xms]
- エラー率 < [X%]
CI 設定の場所:[[.github/workflows/perf.yml / ci/performance.yaml]]
ローカルでの実行方法:
# Run Lighthouse CI against local build
[command — e.g. lhci autorun --config=lighthouserc.js]
# Run load test locally
[command — e.g. k6 run load-tests/api-smoke.js]
予算超過時の対応プロセス
予算超過とは、測定したメトリクスが[連続X回の測定/X分間の継続/単一のデプロイ]にわたって目標を超えることです。
侵害の重大度レベル
| 重大度 | 条件 | 対応時間 | 対応者 |
|---|---|---|---|
| P1 — クリティカル | 本番環境で予算のしきい値の2倍を超過 | 即時 | オンコールエンジニア+チームリード |
| P2 — 高 | 本番環境で予算のしきい値の1.5倍を超過 | 4時間以内 | オンコールエンジニア |
| P3 — 中 | 本番環境でしきい値を超過 | 1スプリント以内 | PR 作成者+チーム |
| P4 — 低 | ステージング環境のみでしきい値を超過 | マージ前 | PR 作成者 |
侵害調査チェックリスト
侵害を検出したら、次のチェックリストを順番に進めてください。
1. リグレッションの原因となったコミットを特定する
# Compare performance across recent deploys
[command — e.g. datadog metrics query, lighthouse-ci compare, git bisect]
2. 侵害を分類する
- コード変更が原因ですか?(新機能、リファクタリング、依存関係の更新)
- インフラストラクチャの変更が原因ですか?(新しいインスタンスタイプ、設定変更)
- 外部要因が原因ですか?(CDN の問題、DNS、上流の依存関係)
- 計測上の異常ですか?(テスト環境の問題、サンプルサイズ)
3. 直ちに行う対応
- 本番環境で P1/P2 に該当し、コードが原因と確認された場合:ロールバックするか、機能フラグを無効にします
- 原因が不明な場合:すぐにロールバックせず、まず追加のデータを収集します
- [#performance / #incidents Slack チャンネル] に、メトリクス名、現在値、予算の目標値、推定原因を知らせます
4. 解決
- 根本原因を修正します。予算のしきい値を調整するだけではいけません
- 予算のしきい値を変更できるのは、チームで議論し、[テックリード / EM] から明示的な承認を得た後だけです
- [パフォーマンスログ / インシデント記録] に侵害を記録します
予算変更ポリシー: 予算のしきい値を緩和できるのは、次の条件を満たす場合に限ります:(a)リグレッションをもたらす機能に、パフォーマンス上のコストを上回る測定可能なビジネス価値があり、(b)変更がレビューされ、[テックリード] の承認を得ていること。
パフォーマンスレビューの実施頻度
| トリガー | 対応 |
|---|---|
| 毎スプリント | P95/P99 レイテンシの傾向を確認し、徐々に進行する性能低下があれば報告します |
| 四半期ごと | パフォーマンス予算を全面的に見直し、ベースラインの更新、目標値の調整、ツールの監査を行います |
| 主要機能のリリース後 | すべての Core Web Vitals と API SLO を再計測し、ベースラインを更新します |
| インフラストラクチャの変更後 | 合成テストスイート全体を再実行し、リグレッションがないことを確認します |
| 依存関係のアップグレード後 | バンドルサイズの差分を確認し、予期しないサイズ増加がないことを確認します |
次回の予定レビュー: [Date] レビュー担当者: [Name / role]
品質チェック
- すべての予算のしきい値が具体的な数値で設定されている(範囲や「TBD」ではない)
- フロントエンド(該当する場合)とバックエンドの両方の目標が定義されている(どちらか一方だけではない)
- 計測ツールが明記され、ダッシュボードまたは設定ファイルへのリンクがある
- CI で少なくとも1つのゲート(ビルド時またはデプロイ時)を適用する設定になっている
- 予算超過への対応プロセスに、具体的な Slack チャンネルと担当者が明記されている
- 予算のしきい値がベースラインの計測値、または妥当な根拠のある目標値に基づいている(根拠なく設定されていない)
- 重要なユーザージャーニーについて、全体平均だけでなく、ジャーニーごとの目標が定義されている
アンチパターン
- 現在のベースラインを計測する前に予算のしきい値を設定しないでください。目標値は実態に基づく必要があります
- 全体平均だけを定義しないでください。重要なユーザージャーニーは大きく異なる可能性があるため、それぞれ個別の予算が必要です
- CI での適用を省略しないでください。ビルドパイプラインで適用されないパフォーマンス予算は守られません
- 担当者やエスカレーション先のチャンネルを明記せずに、予算超過への対応プロセスを定めないでください
- 1つの環境だけに適用される予算を設定しないでください。本番環境とステージング環境の目標値が異なる場合は、それぞれ個別に記載してください