jpskill.com
💼 ビジネス コミュニティ

performance-fundamentals

ループ処理、データ取得、画面描画、データベース処理など負荷の高い処理を見直し、N+1問題や無駄な再描画、メモリリーク、拡張性の問題点などを自動で特定し改善を支援するSkill。

📜 元の英語説明(参考)

Auto-invoke when reviewing loops, data fetching, rendering, database queries, or resource-intensive operations. Identifies N+1 queries, unnecessary re-renders, memory leaks, and scalability issues.

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

一言でいうと

ループ処理、データ取得、画面描画、データベース処理など負荷の高い処理を見直し、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-fundamentals.zip https://jpskill.com/download/18286.zip && unzip -o performance-fundamentals.zip && rm performance-fundamentals.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/18286.zip -OutFile "$d\performance-fundamentals.zip"; Expand-Archive "$d\performance-fundamentals.zip" -DestinationPath $d -Force; ri "$d\performance-fundamentals.zip"

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

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して performance-fundamentals.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → performance-fundamentals フォルダができる
  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 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

パフォーマンスの基礎レビュー

「時期尚早な最適化は諸悪の根源である。しかし、成熟した無知はもっと悪い。」

適用するタイミング

以下のレビュー時にこのスキルを有効化してください。

  • データベースクエリ(特にループ内)
  • React/Vue のレンダリングロジック
  • API のレスポンスペイロード
  • データ変換
  • ファイル操作
  • キャッシュに関する決定

レビューチェックリスト

データベースのパフォーマンス

  • [ ] N+1 クエリがないか: 関連レコードはループではなく、まとめてフェッチされていますか?
  • [ ] インデックス: 頻繁にクエリされるフィールドにインデックスは設定されていますか?
  • [ ] ページネーション: リストエンドポイントは結果をページネーションしていますか?
  • [ ] 必要なフィールドのみを選択: 不必要にレコード全体をフェッチしていませんか?

フロントエンドのパフォーマンス

  • [ ] メモ化: コストの高い計算はキャッシュされていますか?
  • [ ] 再レンダリングの防止: ステートの変更は不必要な再レンダリングを引き起こしませんか?
  • [ ] バンドルサイズ: 重いライブラリは遅延ロードされていますか?
  • [ ] 画像の最適化: 画像は適切なサイズと形式になっていますか?

API のパフォーマンス

  • [ ] レスポンスサイズ: ペイロードは最小限ですか?
  • [ ] 圧縮: gzip/brotli は有効になっていますか?
  • [ ] キャッシュヘッダー: キャッシュ可能なレスポンスはマークされていますか?
  • [ ] 非同期処理: 時間のかかる操作はキューに入れられていますか?

メモリとリソース

  • [ ] クリーンアップ: サブスクリプション/タイマーはクリーンアップされていますか?
  • [ ] メモリリーク: イベントリスナーは削除されていますか?
  • [ ] コネクションプーリング: DB コネクションは再利用されていますか?

よくある間違い(アンチパターン)

1. N+1 クエリ問題

❌ const users = await User.findAll();
   for (const user of users) {
     user.posts = await Post.findByUserId(user.id); // N クエリ!
   }

✅ const users = await User.findAll({
     include: [{ model: Post }] // JOIN を使用した 1 クエリ
   });

2. 不必要な再レンダリング

❌ function Parent() {
     const handleClick = () => {}; // レンダリングごとに新しい関数
     return <Child onClick={handleClick} />;
   }

✅ function Parent() {
     const handleClick = useCallback(() => {}, []);
     return <Child onClick={handleClick} />;
   }

3. レンダリング時の計算

❌ function UserList({ users }) {
     // すべてのレンダリングで実行
     const sorted = users.sort((a, b) => a.name.localeCompare(b.name));
     return <ul>{sorted.map(...)}</ul>;
   }

✅ function UserList({ users }) {
     const sorted = useMemo(
       () => [...users].sort((a, b) => a.name.localeCompare(b.name)),
       [users]
     );
     return <ul>{sorted.map(...)}</ul>;
   }

4. すべてをフェッチする

❌ GET /api/users → すべてのフィールドを持つ 10,000 人のユーザーを返す

✅ GET /api/users?page=1&limit=20&fields=id,name,email

5. クリーンアップの欠如

❌ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     // クリーンアップなし! 永遠に実行されます。
   }, []);

✅ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     return () => clearInterval(interval);
   }, []);

ソクラテス式質問

ジュニアに答えを与える代わりに、これらの質問をしてください。

  1. スケール: 「10,000 個のアイテムがある場合はどうなりますか? 1,000,000 個の場合は?」
  2. クエリ: 「この操作はデータベースクエリを何回実行しますか?」
  3. 再レンダリング: 「このステートが変更されたとき、どのコンポーネントが再レンダリングされますか?」
  4. メモリ: 「不要になった後も参照を保持しているものはありますか?」
  5. ペイロード: 「クライアントはこのデータのすべてを必要としますか?」

Big O クイックリファレンス

パターン 複雑性 10,000 個のアイテムの場合
直接ルックアップ O(1) map.get(key) 1 op
単一ループ O(n) array.find() 10,000 ops
ネストされたループ O(n²) for i { for j } 100,000,000 ops
ソート O(n log n) array.sort() ~130,000 ops

パフォーマンスタゲット

メトリクス ターゲット 測定方法
Time to First Byte (TTFB) < 600ms DevTools Network
Largest Contentful Paint (LCP) < 2.5s Lighthouse
First Input Delay (FID) < 100ms Lighthouse
Cumulative Layout Shift (CLS) < 0.1 Lighthouse
API Response Time < 200ms (p95) サーバーメトリクス

指摘すべき危険信号

フラグ 質問
ループ内のクエリ 「これを 1 つのクエリにまとめることはできますか?」
ページネーションなし 「100,000 件のレコードがある場合はどうなりますか?」
SELECT * 「これらのフィールドはすべて必要ですか?」
localStorage の大きな JSON 「これはページロードを遅くしますか?」
JSX のインライン関数 「これはレンダリングごとに新しい関数を作成しますか?」
クリーンアップなしの setInterval 「コンポーネントがアンマウントされたときに、これは何をクリアしますか?」
同期的なファイル操作 「これは非同期であるべきですか?」
ローディング状態がない 「待機中にユーザーには何が表示されますか?」

クイックウィン

  1. 頻繁にクエリされる DB カラムにインデックスを追加する
  2. すべてのリストエンドポイントをページネーションする
  3. 画面外のコンテンツを遅延ロードする
  4. API レスポンスを圧縮する
  5. useMemo でコストの高い計算をキャッシュする
  6. 検索入力をデバウンスする
  7. 長いリストを仮想化する (react-window)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Performance Fundamentals Review

"Premature optimization is the root of all evil, but mature ignorance is worse."

When to Apply

Activate this skill when reviewing:

  • Database queries (especially in loops)
  • React/Vue render logic
  • API response payloads
  • Data transformations
  • File operations
  • Caching decisions

Review Checklist

Database Performance

  • [ ] No N+1 queries: Are related records fetched in bulk, not loops?
  • [ ] Indexes: Are frequently queried fields indexed?
  • [ ] Pagination: Do list endpoints paginate results?
  • [ ] Select only needed fields: Are we fetching entire records unnecessarily?

Frontend Performance

  • [ ] Memoization: Are expensive computations cached?
  • [ ] Re-render prevention: Will state changes cause unnecessary re-renders?
  • [ ] Bundle size: Are heavy libraries lazy-loaded?
  • [ ] Image optimization: Are images properly sized and formatted?

API Performance

  • [ ] Response size: Is the payload minimal?
  • [ ] Compression: Is gzip/brotli enabled?
  • [ ] Caching headers: Are cacheable responses marked?
  • [ ] Async processing: Are slow operations queued?

Memory & Resources

  • [ ] Cleanup: Are subscriptions/timers cleaned up?
  • [ ] Memory leaks: Are event listeners removed?
  • [ ] Connection pooling: Are DB connections reused?

Common Mistakes (Anti-Patterns)

1. The N+1 Query Problem

❌ const users = await User.findAll();
   for (const user of users) {
     user.posts = await Post.findByUserId(user.id); // N queries!
   }

✅ const users = await User.findAll({
     include: [{ model: Post }] // 1 query with JOIN
   });

2. Unnecessary Re-renders

❌ function Parent() {
     const handleClick = () => {}; // New function every render
     return <Child onClick={handleClick} />;
   }

✅ function Parent() {
     const handleClick = useCallback(() => {}, []);
     return <Child onClick={handleClick} />;
   }

3. Computing in Render

❌ function UserList({ users }) {
     // Runs on every render
     const sorted = users.sort((a, b) => a.name.localeCompare(b.name));
     return <ul>{sorted.map(...)}</ul>;
   }

✅ function UserList({ users }) {
     const sorted = useMemo(
       () => [...users].sort((a, b) => a.name.localeCompare(b.name)),
       [users]
     );
     return <ul>{sorted.map(...)}</ul>;
   }

4. Fetching Everything

❌ GET /api/users → returns 10,000 users with all fields

✅ GET /api/users?page=1&limit=20&fields=id,name,email

5. Missing Cleanup

❌ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     // No cleanup! Runs forever.
   }, []);

✅ useEffect(() => {
     const interval = setInterval(fetchData, 5000);
     return () => clearInterval(interval);
   }, []);

Socratic Questions

Ask the junior these questions instead of giving answers:

  1. Scale: "What happens when there are 10,000 items? 1,000,000?"
  2. Queries: "How many database queries does this operation make?"
  3. Re-renders: "When this state changes, what components re-render?"
  4. Memory: "Is anything holding a reference after it's no longer needed?"
  5. Payload: "Does the client need ALL of this data?"

Big O Quick Reference

Pattern Complexity Example At 10,000 items
Direct lookup O(1) map.get(key) 1 op
Single loop O(n) array.find() 10,000 ops
Nested loops O(n²) for i { for j } 100,000,000 ops
Sort O(n log n) array.sort() ~130,000 ops

Performance Targets

Metric Target Measure With
Time to First Byte (TTFB) < 600ms DevTools Network
Largest Contentful Paint (LCP) < 2.5s Lighthouse
First Input Delay (FID) < 100ms Lighthouse
Cumulative Layout Shift (CLS) < 0.1 Lighthouse
API Response Time < 200ms (p95) Server metrics

Red Flags to Call Out

Flag Question to Ask
Query inside a loop "Can we batch this into one query?"
No pagination "What if there are 100,000 records?"
SELECT * "Do we need all these fields?"
Large JSON in localStorage "Will this slow down page load?"
Inline function in JSX "Does this create a new function every render?"
setInterval without cleanup "What clears this when the component unmounts?"
Synchronous file operations "Should this be async?"
No loading states "What does the user see while waiting?"

Quick Wins

  1. Add indexes to frequently queried DB columns
  2. Paginate all list endpoints
  3. Lazy load below-the-fold content
  4. Compress API responses
  5. Cache expensive computations with useMemo
  6. Debounce search inputs
  7. Virtualize long lists (react-window)