0Pricing
Frontend Academy · レッスン

パフォーマンスのための useMemo と useCallback

useMemo でコストの高い計算をメモ化し、useCallback で関数参照を安定させて、不要な子コンポーネントの再レンダリングを防ぎます。

「パフォーマンスのための useMemo と useCallback」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。

Reactのデフォルト動作

デフォルトでは、Reactは状態が更新されたとき、または親が再レンダリングされたときにコンポーネントを再レンダリングします。propsが変わっていなくても、子コンポーネントも再レンダリングされます。ほとんどのコンポーネントではこれで問題ありません。Reactは高速だからです。

useMemo — 高コストな値をメモ化する

useMemo(fn, deps)は計算結果をキャッシュします。関数は依存関係が変わったときだけ実行されます。レンダリングのたびに繰り返すのが無駄になる高コストな計算に使います。

const expensiveResult = useMemo(() => {
  return items.filter(item => item.category === category).sort((a, b) => a.price - b.price);
}, [items, category]);
// Only recalculates when items or category changes

useCallback — 関数をメモ化する

useCallback(fn, deps)は、depsが変わらない限り同じ参照を維持するメモ化された関数を返します。深くネストされたコンポーネントやメモ化されたコンポーネントにコールバックを渡すときに使います。

const handleDelete = useCallback((id: string) => {
  setItems(prev => prev.filter(item => item.id !== id));
}, []); // stable reference — empty deps because only setItems is used

<ItemList items={items} onDelete={handleDelete} />

React.memo — 再レンダリングをスキップする

React.memo(Component)はコンポーネントをラップし、propsが変わったときだけ再レンダリングするようにします(浅い比較)。安定したコールバックpropsを作るには、useCallbackと組み合わせます。

const MemoItem = React.memo(function Item({ text, onDelete }: ItemProps) {
  console.log('Item rendered:', text); // only logs when props change
  return <li>{text} <button onClick={onDelete}>×</button></li>;
});

// onDelete must be stable (from useCallback) for memo to help

最適化すべきでない場合

早すぎる最適化は落とし穴です。useMemoとuseCallbackには、クロージャの作成やdepsの比較というコストがあります。10個の項目のフィルタリングのように処理が軽い場合は、オーバーヘッドがメリットを上回ります。実際のパフォーマンス問題を計測してから最適化してください。

最適化前のプロファイリング

メモ化を追加する前に、React DevTools Profilerで実際のレンダリング時間を計測します。Profilerを使うと、どのコンポーネントに最も時間がかかっているか、何回レンダリングされているかを確認できます。思い込みではなく、計測結果に基づいて修正してください。

安定した参照のためのuseMemo

useMemoは参照を安定させるためにも便利です。計算自体を高速化するためではなく、下流のメモ化やエフェクトが不要に再実行されるのを防ぐ目的で使います。

// Without useMemo, this creates a new array every render:
const config = useMemo(() => ({ endpoint: '/api', timeout: 5000 }), []);

// Without memoization, useEffect would re-run on every render:
useEffect(() => { initSDK(config); }, [config]);

useCallbackの依存関係

useCallbackにはuseEffectと同じ依存関係のルールが適用されます。コールバックが使用する外側のスコープの変数をすべて含めてください。状態セッター(useStateから返されるもの)は常に安定しているため、depsに含める必要はありません。

useMemoとuseCallbackの関係

useCallback(fn, deps)はuseMemo(() => fn, deps)と同等です。仕組みは同じで、useCallbackは関数のメモ化に特化した構文糖にすぎません。

リスト項目のメモ化

よく使われるパターンは、リストが大きく頻繁に再レンダリングされる場合に、リスト項目のコンポーネントをメモ化することです。useCallbackで安定したコールバックを渡し、メモ化を無効にしないようにします。

const MemoRow = React.memo(Row);
const handleEdit = useCallback((id) => edit(id), []);
const handleDel  = useCallback((id) => remove(id), []);

{rows.map(row => (
  <MemoRow key={row.id} row={row} onEdit={handleEdit} onDelete={handleDel} />
))}

コンテキスト値のメモ化

Context Providerに渡す値をメモ化すると、Providerの親が再レンダリングされるたびにすべてのコンシューマーが再レンダリングされるのを防げます。

const value = useMemo(() => ({ user, login, logout }), [user]);

理解度チェック

useCallbackの目的は何ですか?

復習: useMemoとuseCallback

useMemoは高コストな計算値をキャッシュします。useCallbackは関数参照をキャッシュします。React.memoはpropsが浅い比較で変わらないときに再レンダリングをスキップします。コンポーネント単位のパフォーマンス改善には、これら3つを組み合わせます。まずプロファイリングを行ってください。早すぎるメモ化は、メリットなしに複雑さを増やします。安定した参照により、下流のエフェクトやメモ化処理が再実行されるのを防げます。

よくある質問

「パフォーマンスのための useMemo と useCallback」レッスンは無料ですか?

はい。「パフォーマンスのための useMemo と useCallback」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。

「パフォーマンスのための useMemo と useCallback」で何を学びますか?

useMemo でコストの高い計算をメモ化し、useCallback で関数参照を安定させて、不要な子コンポーネントの再レンダリングを防ぎます。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Frontend Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「パフォーマンスのための useMemo と useCallback」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このFrontend Academyレッスンでコードを書いて実行できますか?

はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. グローバル状態のための useContext
  2. 複雑な状態のための useReducer
  3. パフォーマンスのための useMemo と useCallback
  4. カスタム Hook:再利用可能なロジックの抽出
← Frontend Academyに戻る