logo

UseMemoの使い所 - 計算コストが高いかどうかを見分ける方法

2025-11-18
2 months ago

開発環境

  • react 19.2.0
  • react-dom 19.2.0

前提

useMemo は「重い処理をメモ化することで再計算を避けたいとき」に使うフックです。

ただし、どの処理が "重い" のかは判断が難しく、むやみに使うと逆効果になります。

この記事では、React公式ドキュメントの要点を整理しつつ、実際のコード例を使って「useMemoを使うべきケースをどう判定するか」を解説します。

本題

1. 計算が重いか軽いかを判断する基準

React公式が示すポイントは以下の3つ。

  1. 入力データが大きい(大量の配列、巨大なオブジェクトなど)
  2. 関数が複雑な処理を行っている(ループ・フィルタ・ソート・正規表現など)
  3. 結果の計算に時間がかかる(計測すればわかる)

つまり、コードを読んで明らかに“負荷が高い計算”だけメモ化すれば充分です

2. useMemo を使うべき典型例

❌ 悪い例:軽すぎて useMemo 不要

const priceWithTax = useMemo(() => price * 1.1, [price]);

軽すぎる処理に useMemo を使うと、「メモ化のコスト(比較処理)の方が高い」ため逆に遅くなる可能性があります。

✔️ 良い例:データが大きく、計算が重い

const sortedUsers = useMemo(() => {
  return users
  .slice()
  .sort((a, b) => a.lastLogin - b.lastLogin);
}, [users]);

ユーザーが数千件を超えると、ソート処理のコストはかなり大きいです

さらに、親コンポーネントが再レンダリングされる頻度が高い場合、ここがボトルネックになります。


✔️ 良い例:高コスト計算を UI のたびに走らせたくない

function heavyCalculation(num: number) {
  let result = 0;
  for (let i = 0; i < 10_000_000; i++) {
    result += Math.sqrt(num + i);
  }
  return result;
}

const result = useMemo(() => heavyCalculation(value), [value]);

実際に for を 1,000万回回すと数 ms〜数十 ms かかるため、React が再レンダリングする度にここが動くのは致命的です。

useMemo はこういう “明確に重い” 計算のために存在します。

3. 計算が本当に重いかを「測る」方法

コードを見ても判断できない場合はブラウザで計測します。

function expensiveProcess(data: number[]) {
  console.time("expensiveProcess");
  const result = data.filter((x) => x % 2 === 0).sort();
  console.timeEnd("expensiveProcess");
  return result;
}

const filtered = useMemo(() => expensiveProcess(list), [list]);

あくまでも参考ですが、これが 1ms 以上なら useMemo を検討する価値があるでしょう。

4. useMemo を使うべきかどうかの判断ルール(簡易版)

以下どれかに当てはまれば useMemo の利用を検討すべきでしょう。

  • データ量が大きい(数百〜数千件)
  • ソート・フィルタ・マッピングが複雑
  • 重い数値計算が走る
  • コンポーネントの再レンダリングが多い
  • 計測したら数 ms 以上かかっている

当てはまらないなら useMemo は不要かもしれません。

React 自体の最適化が優秀なので、軽い処理は大抵放置して問題ないです。

さいごに

useMemo は「とりあえず使う」フックではないです。

公式が示すように、明確に “重い” と判断できる処理だけをメモ化することで効果を発揮します。

本当に必要な箇所だけにピンポイントで導入するのが最も効率的です。

参照