mcpField
R
react-performance-optimization

react-performance-optimization

github.com/nickcrew開発621.9k 回インストール17 週間前に更新
リポジトリ

react-performance-optimization について

React 開発者向けに、描画、状態、バンドル、リストの最適化を案内するスキルです。Profiler でボトルネックを特定し、効果を測定してから最適化する方針が特徴です。

主な機能

  1. 01描画のボトルネック特定
  2. 02コンポーネントと計算結果のメモ化
  3. 03コード分割とオンデマンド読み込み
  4. 04大規模リストの仮想化
  5. 05状態管理と並行機能の指針

活用シーン

  1. 01不要なコンポーネント再描画の調査
  2. 02初回読み込みコード量の削減
  3. 03大規模リストやテーブルの応答性改善
  4. 04Profiler による最適化前後の比較

インストール

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

$npx skills add https://github.com/nickcrew/claude-cortex --skill react-performance-optimization

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
code-splitting.md
common-pitfalls.md
concurrent-features.md
memoization.md
profiling-debugging.md
state-management.md
virtualization.md
validation/
rubric.yaml

詳細

React パフォーマンスの最適化

メモ化、コード分割、仮想化、効率的なレンダリング戦略を通じて、React アプリケーションのパフォーマンスを最適化するための専門的なガイダンスです。

このスキルを使用するタイミング

  • レンダリングが遅い React コンポーネントを最適化するとき
  • 初回読み込みを高速化するためにバンドルサイズを削減するとき
  • 大規模なリストやデータテーブルの応答性を向上させるとき
  • 複雑なコンポーネントツリーで不要な再レンダリングを防ぐとき
  • レンダリングの連鎖を減らすために状態管理を最適化するとき
  • コード分割によって体感パフォーマンスを向上させるとき
  • React DevTools Profiler でパフォーマンスの問題をデバッグするとき

コアコンセプト

React のレンダリング最適化

React は、props または state が変更されるとコンポーネントを再レンダリングします。不要な再レンダリングは CPU サイクルを無駄にし、ユーザー体験を損ないます。主な最適化手法:

  • メモ化:コンポーネントのレンダリングと計算値をキャッシュします
  • コード分割:初回読み込みを高速化するため、コードを必要に応じて読み込みます
  • 仮想化:表示中のリスト項目のみをレンダリングします
  • 状態の最適化:レンダリングの連鎖を最小限に抑えるよう状態を構成します
最適化のタイミング
  1. まずプロファイルする:React DevTools Profiler を使って実際のボトルネックを特定します
  2. 効果を測定する:最適化によってパフォーマンスが向上することを確認します
  3. 早すぎる最適化を避ける:高速なコンポーネントは最適化しないでください

クイックリファレンス

必要に応じて詳細なパターンや例を参照してください:

トピック参照ファイル
React.memo、useMemo、useCallback のパターンskills/react-performance-optimization/references/memoization.md
lazy/Suspense によるコード分割、バンドルの最適化skills/react-performance-optimization/references/code-splitting.md
大規模なリストの仮想化(react-window)skills/react-performance-optimization/references/virtualization.md
状態管理の戦略、コンテキストの分割skills/react-performance-optimization/references/state-management.md
useTransition、useDeferredValue(React 18+)skills/react-performance-optimization/references/concurrent-features.md
React DevTools Profiler、パフォーマンスの監視skills/react-performance-optimization/references/profiling-debugging.md
よくある落とし穴とアンチパターンskills/react-performance-optimization/references/common-pitfalls.md

最適化のワークフロー

1. ボトルネックを特定する
# Open React DevTools Profiler
# Record interaction → Analyze flame graph → Find slow components

次の点に注目してください:

  • 黄色または赤色のバーが表示されるコンポーネント(レンダリングが遅い)
  • 不要なレンダリング(props/state が同じ)
  • レンダリングのたびに実行される負荷の高い計算
2. 対象を絞って最適化する

不要な再レンダリングの場合:

  • React.memo でコンポーネントをラップします
  • 安定した関数参照には useCallback を使用します
  • props 内のインラインオブジェクトや配列を確認します

負荷の高い計算の場合:

  • useMemo で結果をキャッシュします
  • 可能であれば計算をレンダリングの外に移します

大規模なリストの場合:

  • react-window で仮想化を実装します
  • 一意で適切なキーを使用します(インデックスは使わないでください)

初回読み込みが遅い場合:

  • React.lazy でコード分割を追加します
  • webpack-bundle-analyzer でバンドルサイズを分析します
  • サイズの大きい依存関係には動的インポートを使用します
3. 改善を確認する
# Record new Profiler session
# Compare before/after metrics
# Ensure optimization actually helped

よくあるパターン

負荷の高いコンポーネントをメモ化する
import { memo } from 'react';

const ExpensiveList = memo(({ items, onItemClick }) => {
  return items.map(item => (
    <Item key={item.id} data={item} onClick={onItemClick} />
  ));
});
計算値をキャッシュする
import { useMemo } from 'react';

function DataTable({ items, filters }) {
  const filteredItems = useMemo(() => {
    return items.filter(item => filters.includes(item.category));
  }, [items, filters]);

  return <Table data={filteredItems} />;
}
安定した関数参照
import { useCallback } from 'react';

function Parent() {
  const handleClick = useCallback((id) => {
    console.log('Clicked:', id);
  }, []);

  return <MemoizedChild onClick={handleClick} />;
}
ルートをコード分割する
import { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./Dashboard'));
const Reports = lazy(() => import('./Reports'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/" element={<Dashboard />} />
        <Route path="/reports" element={<Reports />} />
      </Routes>
    </Suspense>
  );
}
大規模なリストを仮想化する
import { FixedSizeList } from 'react-window';

function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={80}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>{items[index].name}</div>
      )}
    </FixedSizeList>
  );
}

よくある間違い

  1. 過剰なメモ化:単純で高速なコンポーネントはメモ化しないでください(オーバーヘッドが発生します)
  2. インラインオブジェクトや配列:新しい参照はメモ化を無効にします(config={{ theme: 'dark' }})
  3. 依存関係の不足:useCallback/useMemo 内で古いクロージャが使われます
  4. キーにインデックスを使用する:リストの順序が変わると再調整が正しく行われません
  5. 単一の大きなコンテキスト:更新のたびに広範囲の再レンダリングが発生します
  6. プロファイリングをしない:測定せずに最適化すると時間を無駄にします

パフォーマンスのチェックリスト

最適化する前に:

  • React DevTools でプロファイリングし、ボトルネックを特定します
  • パフォーマンス指標のベースラインを測定します

最適化の目標:

  • 安定した props を持つコストの高いコンポーネントをメモ化します
  • useMemo で計算値をキャッシュします(実際にコストが高い場合)
  • メモ化した子コンポーネントに渡す関数には useCallback を使用します
  • ルートや大きなコンポーネントにコード分割を実装します
  • 100 項目を超えるリストを仮想化します
  • リスト項目には安定したキー(一意の ID。インデックスは不可)を指定します
  • 更新頻度に応じて状態を分割します
  • 応答性を高めるため、並行機能(useTransition、useDeferredValue)を使用します

最適化した後:

  • 再度プロファイリングして改善を確認します
  • バンドルサイズの削減を確認します(該当する場合)
  • 機能にリグレッションがないことを確認します

リソース

コメント