mcpField
P
performance-review

performance-review

github.com/shiplightaiテスト・品質2407 回インストール16 週間前に更新
リポジトリ

performance-review について

performance-review は、リリース前、性能低下の調査、高トラフィックのイベント前に Web アプリの性能を測定・評価する手順です。ブラウザで Core Web Vitals、読み込み、リソース、実行時の挙動を測り、レポート、修正案、YAML 回帰テストを作成します。

主な機能

  1. 01Core Web Vitals の測定
  2. 02ページ読み込み指標の評価
  3. 03リソースとバンドルの確認
  4. 04実行時パフォーマンス分析
  5. 05性能レポートと YAML 回帰テスト
  6. 06クイック・標準・詳細レビュー

活用シーン

  1. 01リリース前に主要ページの性能を確認
  2. 02読み込みの遅さや操作の遅延を調査
  3. 03新しい依存関係やサードパーティスクリプトの影響を評価
  4. 04高トラフィックイベント向けの性能基準を設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/shiplightai/agent-skills --skill performance-review

インストール後、Claude Code で/performance-reviewを入力して読み込まれたか確認します。

詳細

パフォーマンスレビュー

Google の Core Web Vitals のしきい値と業界ベンチマークに照らして、アプリケーションのパフォーマンスを測定・評価します。このレビューでは、開発中には見えにくいものの実際のユーザーに影響するパフォーマンス上の問題、つまりバンドルの肥大化、レイアウトシフト、操作の遅延、画像の最適化不足、レンダリングを妨げるリソースを検出します。

使用するタイミング

次の場合に /performance-review を使用してください。

  • リリース前、または大規模な機能追加後
  • ページの読み込みが遅く感じられるものの、原因がわからない場合
  • トラフィックの多いイベントに備える場合
  • 新しい依存関係やサードパーティ製スクリプトの追加後
  • SEO のランキングがパフォーマンススコアに左右される場合
  • ユーザーから遅延や離脱の報告があった場合

参照する標準

  • Google Core Web Vitals — LCP、INP、CLS(2024 年のしきい値)
  • Google Lighthouse — パフォーマンスのスコアリング方法
  • HTTP Archive — ウェブパフォーマンスのベンチマーク(中央値、p75、p90)
  • Web.dev Performance Guidelines — ベストプラクティス
  • RAIL Model — 応答、アニメーション、アイドル、読み込みの予算

フェーズの概要

Phase 1: EDUCATE   → Performance impact on business and what we measure
Phase 2: SCOPE     → Identify key pages, performance budget, baseline
Phase 3: ANALYZE   → Browser-based performance measurement
Phase 4: REPORT    → Findings with metrics, scores, and comparisons
Phase 5: REMEDIATE → Fix guidance + YAML regression tests

フェーズ 1:理解する

重要な理由: ページの読み込みが 1 秒遅れると、コンバージョンが 7%低下します(Akamai)。Google は 2021 年から Core Web Vitals をランキングシグナルとして使用しています。モバイル訪問者の 53%は、読み込みに 3 秒を超えるページから離脱します(Google)。Amazon の調査では、遅延が 100ms 増えるごとに売上が 1%減少します。パフォーマンスは機能の一つであり、その欠如はバグです。

このレビューでは、静的解析だけではなく、ブラウザーで実際のパフォーマンスを測定します。実際の読み込み時間、レンダリングの挙動、操作への応答性を記録します。


フェーズ 2:範囲を定める

コンテキストを収集する
  1. コードベースから自動検出する:

    • ビルドシステム(Webpack、Vite、Next.js など)
    • バンドル分析の設定(ある場合)
    • 画像最適化パイプライン(sharp、next/image など)
    • フォントの読み込み方式
    • コード分割の設定
    • Service Worker/キャッシュ戦略
    • CDN の設定
  2. ユーザーに質問する(一度に 1 つずつ):

    • 対象 URL:アプリはどこで実行されていますか?(現実的な測定には本番環境を推奨)
    • 重要なページ:パフォーマンス上、最も重要なページはどれですか?(ランディングページ、主要機能のページ、データ量の多いページを推奨)
    • パフォーマンス予算:既存の目標はありますか?(デフォルト:Core Web Vitals の「良好」なしきい値)
    • 既知の懸念事項:遅く感じるページはありますか?(任意)
  3. 測定計画を定める:

    • テスト対象ページ(重要なページ 3~5 件)
    • 条件:デスクトップとモバイルのシミュレーション(Moto G4/低速 4G)
    • 指標:Core Web Vitals と補足指標
    • ベースライン:初回実行で比較用のベースラインを確立

フェーズ 3:分析する

record_evidence: true を指定して new_session でブラウザーセッションを開きます。対象範囲の各ページについて、すべての測定カテゴリを実行します。

カテゴリ A:Core Web Vitals(CWV)
チェック ID指標良好改善が必要不良方法
CWV-01LCP(最大コンテンツの描画)≤2.5s2.5-4.0s>4.0sLCP エントリを PerformanceObserver で取得
CWV-02INP(次の描画までのインタラクション)≤200ms200-500ms>500ms主要なインタラクティブ要素をクリックし、遅延を測定
CWV-03CLS(累積レイアウトシフト)≤0.10.1-0.25>0.25layout-shift エントリを PerformanceObserver で取得

ブラウザーでの検証: 各ページに移動し、JavaScript で指標を取得します。

// LCP
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lcp = entries[entries.length - 1];
  console.log('LCP:', lcp.startTime);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// CLS
let clsValue = 0;
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) clsValue += entry.value;
  }
  console.log('CLS:', clsValue);
}).observe({ type: 'layout-shift', buffered: true });
カテゴリ B:ページ読み込みパフォーマンス(LOAD)
チェック IDチェック項目しきい値方法
LOAD-01最初のバイトまでの時間(TTFB)≤800msperformance.timing.responseStart - navigationStart
LOAD-02First Contentful Paint(FCP)≤1.8sperformance.getEntriesByName('first-contentful-paint')
LOAD-03DOM コンテンツ読み込み完了≤2.0sperformance.timing.domContentLoadedEventEnd
LOAD-04ページ全体のサイズ≤3MB(モバイル)/≤5MB(デスクトップ)performance.getEntriesByType('resource') の合計
LOAD-05HTTP リクエスト数≤50リソースエントリーをカウント
LOAD-06操作可能になるまでの時間(TTI)≤3.8sロングタスクの分析
LOAD-07Total Blocking Time(TBT)≤200msロングタスク(50ms を超える部分)の合計
LOAD-08Speed Index≤3.4s視覚的な進行状況の分析

ブラウザーでの検証: Performance API と performance.getEntries() を使用して、すべての指標を収集します。

カテゴリ C:リソースの最適化(RES)
チェック IDチェック項目基準方法
RES-01画像に最新の形式(WebP/AVIF)を使用しているWeb.dev画像 URL と Content-Type を確認
RES-02画像が適切なサイズである(大きすぎない)Web.dev表示サイズと実際のサイズを比較
RES-03画像で遅延読み込みを使用している(ファーストビューより下)Web.devファーストビューより下の画像に loading="lazy" が指定されているか確認
RES-04画像に明示的な寸法(width/height)があるCLS の防止width/height 属性を確認
RES-05CSS がレンダリングをブロックしていない(またはクリティカル CSS をインライン化している)Web.devCSS の読み込み方法を確認
RES-06JavaScript が遅延または非同期で読み込まれているWeb.devスクリプトの読み込み属性を確認
RES-07フォントで font-display: swap または optional を使用しているWeb.dev@font-face 宣言を確認
RES-08フォントが事前読み込みされているWeb.dev<link rel="preload" as="font"> があるか確認
RES-09Gzip/Brotli 圧縮が有効になっているHTTP のベストプラクティスContent-Encoding ヘッダーを確認
RES-10HTTP/2 または HTTP/3 が使用されているHTTP のベストプラクティスPerformance API でプロトコルを確認
RES-11キャッシュヘッダーが適切に設定されているHTTP のベストプラクティス静的アセットの Cache-Control を確認
RES-12未使用の CSS/JS が読み込まれていないバンドルの効率性Page.startJSCoverage/startCSSCoverage でカバレッジを確認

ブラウザーでの検証: JavaScript を使用して、読み込まれたすべてのリソース、その種類、サイズ、読み込み属性を調べます。詳細なリソース指標を取得するには、performance.getEntriesByType('resource') を使用します。

カテゴリ D:バンドル分析(BUN)
チェック IDチェック項目しきい値方法
BUN-01メイン JS バンドルのサイズ≤250KB(gzip 圧縮後)メインバンドルの転送サイズを確認
BUN-02JS の合計サイズ≤500KB(gzip 圧縮後)すべての JS の転送サイズを合計
BUN-03CSS の合計サイズ≤100KB(gzip 圧縮後)すべての CSS の転送サイズを合計
BUN-04コード分割が実装されているベストプラクティス複数の JS チャンクがあるか確認
BUN-05重複する依存関係がないバンドルの効率性チャンクの内容を分析して重複を確認
BUN-06ツリーシェイキングが効果的に機能しているバンドルの効率性既知の大規模な未使用エクスポートがないか確認
BUN-07本番環境でソースマップが公開されていないセキュリティ/パフォーマンス.map ファイルにアクセスできるか確認
BUN-08サードパーティ JS の予算JS 全体の ≤30%サードパーティとファーストパーティの比率を計算

ブラウザーでの検証: Performance API を使用して転送サイズを測定します。ソースマップの URL を確認します。スクリプトのドメインのオリジンを分析します。

カテゴリ E:実行時パフォーマンス(RUN)
チェック IDチェック項目しきい値方法
RUN-01操作中に長時間タスクが発生しない50ms 超 = 長時間タスク長時間タスクに対して PerformanceObserver を使用
RUN-02スクロールが滑らかに動作する60fpsページをスクロールし、フレーム落ちを測定
RUN-03アニメーションのパフォーマンス60fpsアニメーションを実行し、カクつきを測定
RUN-04メモリ使用量が安定している(リークがない)増加傾向がないperformance.memory を時間をおいて測定
RUN-05DOM ノードが過剰に存在しない≤1500 ノードdocument.querySelectorAll('*').length をカウント
RUN-06レイアウトのスラッシングがない強制リフロー 0 件強制的なスタイル再計算を監視
RUN-07イベントリスナーが効率的であるリスナーが過剰でないスロットリングされていない scroll/resize リスナーを確認

ブラウザーでの検証: JavaScript でパフォーマンス指標を測定しながら、アプリを操作します。


フェーズ 4:レポート

構造化レポートを shiplight/reports/performance-review-{date}.md に保存します。

# Performance Review Report
**Date:** {date}
**URL:** {url}
**Pages tested:** {list}
**Conditions:** Desktop + Mobile (simulated Moto G4 / Slow 4G)

## Overall Score: {X}/10 | Confidence: {X}%

## Core Web Vitals Summary
| Metric | Desktop | Mobile | Status |
|--------|---------|--------|--------|
| LCP | 1.8s | 3.2s | ⚠️ Mobile needs work |
| INP | 95ms | 180ms | ✅ Good |
| CLS | 0.05 | 0.15 | ⚠️ Mobile needs work |

## Score Breakdown
| Category | Score | Findings |
|----------|-------|----------|
| Core Web Vitals (CWV) | 6/10 | 1 high, 1 medium |
| Page Load (LOAD) | 7/10 | 1 high |
| Resources (RES) | 5/10 | 2 high, 2 medium |
| Bundle (BUN) | 6/10 | 1 high, 1 medium |
| Runtime (RUN) | 8/10 | 1 medium |

## Resource Waterfall
(Top 10 slowest resources with load times)

## Bundle Breakdown
| Category | Size (gzipped) | Budget | Status |
|----------|---------------|--------|--------|
| First-party JS | 180KB | 250KB | ✅ |
| Third-party JS | 220KB | 150KB | ❌ Over budget |
| CSS | 45KB | 100KB | ✅ |
| Images | 1.2MB | 1.5MB | ✅ |
| Fonts | 85KB | 100KB | ✅ |

## Findings
(structured findings with metrics and evidence)
信頼度スコア
  • 90-100%:ブラウザーで具体的な値を測定済み(例:LCP:3.2s)
  • 70-89%:リソース分析から導出(例:最適化されていない画像を検出)
  • 50-69%:コードレベルのパターン(例:遅延読み込み属性が見つからない)
  • 50% 未満:報告しない

フェーズ 5:修正

1. 修正の指針(例)
#### RES-01: Images not using modern formats
**Impact:** ~40% larger images than necessary, adds ~500KB to page weight
**Current:** 8 PNG images totaling 1.2MB
**Fix:** Convert to WebP with fallback:
- Use `<picture>` with WebP source and PNG fallback
- Or use Next.js `<Image>` / `sharp` for automatic format negotiation
- Expected savings: ~480KB (40% reduction)
**Priority files:**
- /images/hero.png (320KB → ~190KB as WebP)
- /images/features.png (280KB → ~165KB as WebP)
2. YAML 回帰テスト
- name: cwv-01-lcp-under-threshold
  description: Verify Largest Contentful Paint is under 2.5 seconds
  severity: high
  standard: Core-Web-Vitals-LCP
  steps:
    - description: Set up an LCP observer before navigation
      js: |
        // Set up LCP observer before navigation
        await page.evaluateOnNewDocument(() => {
          window.__lcp = 0;
          new PerformanceObserver((list) => {
            const entries = list.getEntries();
            window.__lcp = entries[entries.length - 1].startTime;
          }).observe({ type: 'largest-contentful-paint', buffered: true });
        });
    - URL: /
    - WAIT_UNTIL: Page has fully loaded including all images and content
      timeout_seconds: 30
    - description: Assert Largest Contentful Paint is under 2.5s
      js: |
        const lcp = await page.evaluate(() => window.__lcp);
        if (lcp > 2500) {
          throw new Error(`LCP is ${lcp}ms, exceeds 2500ms threshold`);
        }
        console.log(`LCP: ${lcp}ms (threshold: 2500ms)`);
    - VERIFY: Page loaded with Largest Contentful Paint under 2.5 seconds

すべての YAML テストを shiplight/tests/performance-review.test.yaml に保存します。


詳細レベル

  • --quick:メインページの Core Web Vitals のみ。約2分。
  • デフォルト:主要ページの全カテゴリをデスクトップとモバイルで確認。約8~12分。
  • --thorough:全カテゴリに加え、追加ページ、統計的信頼性を高めるための複数回の実行、実行時プロファイリングを実施。約20~30分。

ヒント

  • 本番環境(または本番に近いビルド)で測定します。開発モードのパフォーマンスは実態を反映しません。
  • 複数回実行します。パフォーマンス測定値にはばらつきがあるため、単一のデータ点ではなく傾向を確認します。
  • モバイルシミュレーションではデスクトップで見つからない問題が明らかになります。必ず両方をテストします。
  • performance.getEntries() を使用します。ブラウザーで得られるパフォーマンスデータの中で、最も情報量が豊富です。
  • まず Core Web Vitals に注目します。Google がランキングに使用する指標です。
  • close_session でセッションを閉じ、証拠の提示には generate_html_report を使用します。

コメント