jpskill.com
🛠️ 開発・MCP コミュニティ

performance-reviewer

コードのパフォーマンス問題を洗い出し、N+1クエリやメモリリーク、非効率なアルゴリズムなどをチェックして、改善の機会を見つけ出すことで、システムの速度向上や資源の有効活用を支援するSkill。

📜 元の英語説明(参考)

Review code for performance issues and optimization opportunities. Use when someone needs to check for N+1 queries, unnecessary re-renders, memory leaks, inefficient algorithms, missing indexes, or bundle size regressions. Trigger words: performance review, slow query, N+1, memory leak, bundle size, latency, optimization, re-render, Big O.

🇯🇵 日本人クリエイター向け解説

一言でいうと

コードのパフォーマンス問題を洗い出し、N+1クエリやメモリリーク、非効率なアルゴリズムなどをチェックして、改善の機会を見つけ出すことで、システムの速度向上や資源の有効活用を支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o performance-reviewer.zip https://jpskill.com/download/15248.zip && unzip -o performance-reviewer.zip && rm performance-reviewer.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15248.zip -OutFile "$d\performance-reviewer.zip"; Expand-Archive "$d\performance-reviewer.zip" -DestinationPath $d -Force; ri "$d\performance-reviewer.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して performance-reviewer.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → performance-reviewer フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

パフォーマンスレビュー担当

概要

このスキルは、コード変更を分析して、パフォーマンスの低下や最適化の機会を検出します。N+1データベースクエリ、Reactコンポーネントでの不要な再レンダリング、データベースインデックスの欠落、最適化されていないループ、バンドルサイズの増加など、一般的な問題を本番環境に到達する前に捕捉します。

指示

DiffまたはPRの分析

  1. Diffを取得します: git diff main...HEAD または git diff <base>...<head>
  2. 変更された各ファイルについて、以下のパフォーマンスカテゴリに対して評価します。

データベースとクエリ:

  • ループ内のクエリ(N+1パターン)を探します
  • WHERE句の欠落またはフルテーブルスキャンを確認します
  • WHEREJOIN、またはORDER BYで使用されるカラムにインデックスが欠落していないか特定します
  • 特定のカラムのみが必要な場合にSELECT *をフラグします
  • LIMITのない無制限のクエリに注意します

フロントエンドとレンダリング:

  • React: propsとして渡される高コストな計算にuseMemo/useCallbackが欠落していないか確認します
  • 大規模なコンポーネントツリーの不要な再レンダリングを引き起こす状態更新を探します
  • レンダリング時にインラインオブジェクト/配列の作成をフラグします(レンダリングごとに新しい参照を作成します)
  • 大きなバンドルインポートを確認します(import momentdayjsを提案)

アルゴリズムとデータ構造:

  • O(n log n)の代替手段が存在する場合、O(n²)以上のアルゴリズムをフラグします
  • SetまたはMapを使用する必要がある繰り返しの配列検索を探します
  • ループ内の文字列連結を特定します(StringBuilder/joinを提案)

メモリとリソース:

  • useEffectでのクリーンアップの欠落を確認します(イベントリスナー、インターバル、サブスクリプション)
  • 決してトリミングされない増え続ける配列/オブジェクトを探します
  • 接続プール制限の欠落または閉じられていないファイルハンドルをフラグします

ネットワークとI/O:

  • 並列化できるシーケンシャルAPI呼び出しを特定します(Promise.all
  • リストエンドポイントでのページネーションの欠落を確認します
  • 高コストまたは繰り返される操作に対するキャッシュの欠落をフラグします

出力形式

見つかった各問題について、以下を報告します。

  • ファイルと行番号
  • カテゴリ(Database、Frontend、Algorithm、Memory、Network)
  • 重要度(Critical、Warning、Info)
  • 問題点(具体的な説明)
  • 推奨される修正(具体的なコード提案)

重要度のガイドライン

  • Critical: 本番環境で目に見える劣化を引き起こします(ループ内のN+1、大規模なデータセットでのO(n²)、メモリリーク)
  • Warning: スケールによっては問題を引き起こす可能性があります(インデックスの欠落、不要な再レンダリング、シーケンシャルAPI呼び出し)
  • Info: 最適化の機会、緊急ではありません(バンドルサイズの提案、軽微なリファクタリング)

例1: N+1クエリの検出

入力diff:

# api/views.py
def list_orders(request):
    orders = Order.objects.filter(user=request.user)
    result = []
    for order in orders:
        items = OrderItem.objects.filter(order=order)  # ← orderごとのクエリ
        result.append({
            "id": order.id,
            "total": order.total,
            "items": [{"name": i.product.name, "qty": i.quantity} for i in items]
        })
    return JsonResponse(result, safe=False)

出力:

🔴 Critical — Database N+1 Query
  File: api/views.py:5-8
  Issue: OrderItemクエリがorderごとに1回実行され、さらに各i.product.nameが
         別のクエリをトリガーします。50件のorderにそれぞれ3つのitemがある場合 = 201件のクエリ。
  Fix: select_relatedとprefetch_relatedを使用します:
    orders = Order.objects.filter(user=request.user).prefetch_related(
        Prefetch('items', queryset=OrderItem.objects.select_related('product'))
    )
  Result: order数に関係なく3件のクエリに削減されます。

例2: Reactの再レンダリングの問題

入力diff:

function UserList({ users, onSelect }) {
  return (
    <div>
      {users.map(user => (
        <UserCard
          key={user.id}
          user={user}
          style={{ padding: 16, margin: 8 }}
          onClick={() => onSelect(user.id)}
        />
      ))}
    </div>
  );
}

出力:

🟡 Warning — Unnecessary Re-Renders
  File: components/UserList.jsx:6-7
  Issue: インラインオブジェクト`style={{ padding: 16, margin: 8 }}`とアロー関数
         `() => onSelect(user.id)`は、レンダリングごとに新しい参照を作成し、
         usersが変更されていない場合でも、すべてのUserCardコンポーネントを再レンダリングさせます。
  Fix:
    const cardStyle = useMemo(() => ({ padding: 16, margin: 8 }), []);
    const handleClick = useCallback((id) => onSelect(id), [onSelect]);
    // Then: style={cardStyle} onClick={() => handleClick(user.id)}
  Impact: 100人以上のusersがいる場合、親のレンダリングごとに約100回の不要なDOM diffing操作を防ぎます。

ガイドライン

  • 既存の問題ではなく、diffによって導入された問題に焦点を当てます
  • Criticalな問題を優先します — Infoの提案のリストに埋もれさせないでください
  • 常に具体的な修正提案を提供し、「これを最適化する」だけではいけません
  • スケールを考慮します: 5要素の配列でのO(n²)ループは問題ありません。ユーザー生成データではそうではありません
  • キャッシュを提案する場合は、何をキャッシュするか、および無効化戦略を指定します
  • 無視できる程度の改善のために可読性を損なうマイクロ最適化をフラグしないでください
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Performance Reviewer

Overview

This skill analyzes code changes for performance regressions and optimization opportunities. It catches common issues like N+1 database queries, unnecessary re-renders in React components, missing database indexes, unoptimized loops, and bundle size increases before they reach production.

Instructions

Analyzing a Diff or PR

  1. Get the diff: git diff main...HEAD or git diff <base>...<head>
  2. For each changed file, evaluate against these performance categories:

Database & Queries:

  • Look for queries inside loops (N+1 pattern)
  • Check for missing WHERE clauses or full table scans
  • Identify missing indexes on columns used in WHERE, JOIN, or ORDER BY
  • Flag SELECT * when only specific columns are needed
  • Watch for unbounded queries without LIMIT

Frontend & Rendering:

  • React: Check for missing useMemo/useCallback on expensive computations passed as props
  • Look for state updates that trigger unnecessary re-renders of large component trees
  • Flag inline object/array creation in render (creates new reference every render)
  • Check for large bundle imports (import moment → suggest dayjs)

Algorithm & Data Structures:

  • Flag O(n²) or worse algorithms when O(n log n) alternatives exist
  • Look for repeated array searches that should use a Set or Map
  • Identify string concatenation in loops (suggest StringBuilder/join)

Memory & Resources:

  • Check for missing cleanup in useEffect (event listeners, intervals, subscriptions)
  • Look for growing arrays/objects that are never trimmed
  • Flag missing connection pool limits or unclosed file handles

Network & I/O:

  • Identify sequential API calls that could be parallelized (Promise.all)
  • Check for missing pagination on list endpoints
  • Flag missing caching for expensive or repeated operations

Output Format

For each issue found, report:

  • File and line number
  • Category (Database, Frontend, Algorithm, Memory, Network)
  • Severity (Critical, Warning, Info)
  • What's wrong (specific description)
  • Suggested fix (concrete code suggestion)

Severity Guidelines

  • Critical: Will cause visible degradation in production (N+1 in a loop, O(n²) on large datasets, memory leak)
  • Warning: May cause issues at scale (missing index, unnecessary re-renders, sequential API calls)
  • Info: Optimization opportunity, not urgent (bundle size suggestion, minor refactor)

Examples

Example 1: N+1 Query Detection

Input diff:

# api/views.py
def list_orders(request):
    orders = Order.objects.filter(user=request.user)
    result = []
    for order in orders:
        items = OrderItem.objects.filter(order=order)  # ← query per order
        result.append({
            "id": order.id,
            "total": order.total,
            "items": [{"name": i.product.name, "qty": i.quantity} for i in items]
        })
    return JsonResponse(result, safe=False)

Output:

🔴 Critical — Database N+1 Query
  File: api/views.py:5-8
  Issue: OrderItem query executes once per order, plus each i.product.name
         triggers another query. For 50 orders with 3 items each = 201 queries.
  Fix: Use select_related and prefetch_related:
    orders = Order.objects.filter(user=request.user).prefetch_related(
        Prefetch('items', queryset=OrderItem.objects.select_related('product'))
    )
  Result: Reduces to 3 queries regardless of order count.

Example 2: React Re-render Issue

Input diff:

function UserList({ users, onSelect }) {
  return (
    <div>
      {users.map(user => (
        <UserCard
          key={user.id}
          user={user}
          style={{ padding: 16, margin: 8 }}
          onClick={() => onSelect(user.id)}
        />
      ))}
    </div>
  );
}

Output:

🟡 Warning — Unnecessary Re-renders
  File: components/UserList.jsx:6-7
  Issue: Inline object `style={{ padding: 16, margin: 8 }}` and arrow function
         `() => onSelect(user.id)` create new references every render, causing
         all UserCard components to re-render even when users haven't changed.
  Fix:
    const cardStyle = useMemo(() => ({ padding: 16, margin: 8 }), []);
    const handleClick = useCallback((id) => onSelect(id), [onSelect]);
    // Then: style={cardStyle} onClick={() => handleClick(user.id)}
  Impact: With 100+ users, prevents ~100 unnecessary DOM diffing operations per parent render.

Guidelines

  • Focus on issues introduced by the diff, not pre-existing problems
  • Prioritize Critical issues — don't bury them in a list of Info suggestions
  • Always provide concrete fix suggestions, not just "optimize this"
  • Consider the scale: an O(n²) loop on a 5-element array is fine; on user-generated data it's not
  • When suggesting caching, specify what to cache and invalidation strategy
  • Don't flag micro-optimizations that harm readability for negligible gain