react-component-performance
ReactコンポーネントのパフォーマンスBugを分析・最適化するスキルです。低速なレンダリング、不要な再レンダリング、重い計算処理、リストの描画遅延などを対象とし、Reactコンポーネントのプロファイリングや再レンダリングの削減、UI更新の高速化を求められた際に使用します。
description の原文を見る
Analyze and optimize React component performance issues (slow renders, re-render thrash, laggy lists, expensive computations). Use when asked to profile or improve a React component, reduce re-renders, or speed up UI updates in React apps.
SKILL.md 本文
React コンポーネントパフォーマンス
概要
レンダリングのボトルネックを特定し、高コストな更新を分離し、UI の動作を変えない形で対象を絞った最適化を適用します。
ワークフロー
- 遅延を再現するか説明する。
- 何が再レンダリングを引き起こしているかを特定する(状態更新、props の変動、エフェクト)。
- 急速に変動する状態を重い部分木から分離する。
- props とハンドラーを安定化させ、効果がある場合はメモ化する。
- 高コストな処理を削減する(計算、DOM サイズ、リスト長)。
- 検証:React DevTools Profiler を開く → インタラクションを記録 → Flamegraph でレンダリングに ~16 ms 以上かかっているコンポーネントを検査 → 最適化前のベースライン記録と比較する。
チェックリスト
- 計測:React DevTools Profiler またはレンダリングログを使用してベースラインを取得する。
- 変動を見つける:タイマー、スクロール、入力、またはアニメーションで更新される状態を特定する。
- 分割:tick する状態を子要素に移動し、重いリストは静的に保つ。
- メモ化:props が安定している場合のみ、leaf 行を
memoでラップする。 - Props を安定化:ハンドラーと派生値に
useCallback/useMemoを使う。 - レンダー内での派生処理を避ける:事前計算するか、メモ化されたヘルパー内で計算する。
- リストサイズを制御:長いリストはウィンドウ化/仮想化し、隠れたアイテムのレンダリングを避ける。
- キー:安定したキーを確保する;順序が変わる可能性がある場合はインデックスを避ける。
- エフェクト:依存配列を確認する;毎回のレンダリングで再実行されるエフェクトを避ける。
- スタイル/レイアウト:高コストなレイアウトスラッシングや大規模な Markdown/diff レンダリングに注意する。
最適化パターン
Tick する状態を分離する
タイマーやアニメーションカウンターを子要素に移動し、親リストが毎回の tick で再レンダリングされないようにする。
// ❌ Before – 親全体(とリスト)が毎秒再レンダリングされる
function Dashboard({ items }: { items: Item[] }) {
const [tick, setTick] = useState(0);
useEffect(() => {
const id = setInterval(() => setTick(t => t + 1), 1000);
return () => clearInterval(id);
}, []);
return (
<>
<Clock tick={tick} />
<ExpensiveList items={items} /> {/* 毎秒再レンダリング */}
</>
);
}
// ✅ After – <Clock> だけが再レンダリング;リストはそのまま
function Clock() {
const [tick, setTick] = useState(0);
useEffect(() => {
const id = setInterval(() => setTick(t => t + 1), 1000);
return () => clearInterval(id);
}, []);
return <span>{tick}s</span>;
}
function Dashboard({ items }: { items: Item[] }) {
return (
<>
<Clock />
<ExpensiveList items={items} />
</>
);
}
useCallback + memo でコールバックを安定化する
// ❌ Before – 毎回のレンダリングで新しいハンドラーの参照が生成され、Row の memo を無効化する
function List({ items }: { items: Item[] }) {
const handleClick = (id: string) => console.log(id); // 毎回のレンダリングで新しい参照
return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />);
}
// ✅ After – 安定したハンドラー;Row は自身の item が変わったときのみ再レンダリング
const Row = memo(({ item, onClick }: RowProps) => (
<li onClick={() => onClick(item.id)}>{item.name}</li>
));
function List({ items }: { items: Item[] }) {
const handleClick = useCallback((id: string) => console.log(id), []);
return items.map(item => <Row key={item.id} item={item} onClick={handleClick} />);
}
派生データはレンダー外で処理する
// ❌ Before – 毎回のレンダリングで再計算される
function Summary({ orders }: { orders: Order[] }) {
const total = orders.reduce((sum, o) => sum + o.amount, 0); // 毎回のレンダリングで実行
return <p>Total: {total}</p>;
}
// ✅ After – orders が変わったときのみ再計算される
function Summary({ orders }: { orders: Order[] }) {
const total = useMemo(() => orders.reduce((sum, o) => sum + o.amount, 0), [orders]);
return <p>Total: {total}</p>;
}
その他のパターン
- 行を分割:リスト行をメモ化されたコンポーネントに抽出し、props を限定する。
- 重いレンダリングを遅延:高コストなコンテンツは遅延レンダリングまたは展開まで非表示にする。
プロファイリング検証ステップ
- React DevTools → Profiler タブを開く。
- Record をクリック、遅い操作を実行してから Stop をクリック。
- Flamegraph ビューに切り替え;時間が ~16 ms を超えるコンポーネントラベルが付いたバーは候補となる。
- Ranked chart を使用して self レンダリング時間でソートし、上位の犯人を対象にする。
- 一度に 1 つの最適化を適用し、再記録し、レンダリング数と期間をベースラインと比較する。
参考例
ユーザーが具体的なリファクタリング例を求める場合は references/examples.md を読み込む。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- dimillian
- リポジトリ
- dimillian/skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/dimillian/skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。