ReactのuseMemoは、計算コストの高い処理をメモ化することで、不要な再実行を避けてパフォーマンスを向上させるためのフックです。しかし現実の開発現場では、useMemoがパフォーマンス改善のためにとりあえず書かれているケースや、実は再計算しても大した影響がない処理にまで適用されてしまっていることも少なくありません。

本稿では、useMemoが使われているコードに対して、レビューアーがどのようにその妥当性を判断し、最適化と可読性のバランスを見極めるかの観点を整理します。

よくある構造:useMemoの安易な使用

無条件にuseMemoが適用されている構造
const sorted = useMemo(() => {
  return items.slice().sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
@Reviewer
`items` がそもそも再生成される頻度が少ない場合、この `useMemo` は過剰です。配列のサイズや処理負荷が小さい場合は、メモ化による複雑性のほうがコストになります。

たとえ useMemo によって再計算が防げたとしても、それが体感レベルや実行コストに影響を与えないのであれば、むしろ保守性を犠牲にしているだけという判断もあります。

useMemoをレビューするための基本的な問い

useMemoが書かれていたとき、レビューアーがまず問うべきは次の2点です。

  • 再計算にどれだけのコストがあるか
  • 再計算の発生頻度がどの程度の影響を及ぼすか

たとえば以下のような処理であれば、useMemoを使う意義が出てきます。

  • 数千件のデータソート
  • canvasやSVGなどの描画前加工
  • カスタムフィルタの事前計算

逆に、以下のような処理はメモ化の必要性が薄く、むしろ読みづらさを生む副作用を持ちます。

  • 小規模データの単純なmap/filter
  • ループ1回分の数値変換
  • 単純な文字列生成

コードの明瞭性を下げる副作用

useMemoを使うことでコードの目的が読みにくくなるケースがあります。

処理の目的が読みづらくなる例
const enhanced = useMemo(() => enhance(data), [data]);

このような場合、関数の中身が見えないと何をしているか分かりません。特に、以下のような構造が見られたときは注意が必要です。

  • useMemo(() => ...) の中が長すぎる
  • 名前付けが曖昧(processed, computed, value など)
  • 実態が単なる関数呼び出しになっている
Comment
@Reviewer
メモ化処理の内容が分かりづらく、関数名の抽象度も高いため、コードの意図が明示されていません。パフォーマンス上の必要性がなければ、通常の関数呼び出しに戻すことで可読性が上がります。

useMemoの代替手段は本当に必要か

レビューアーとしては、次のような指摘も選択肢として持つべきです。

  • 通常の関数スコープ内に出すだけで十分では?
  • 関数コンポーネントの再実行による再計算が本当にボトルネックになっているか?
  • メモ化の恩恵を確認するベンチマークや測定がされているか?

パフォーマンスの最適化は定量的であるべきで、思い込みでの最適化は逆効果になり得ます。

useMemoに関するレビュー指摘テンプレート例

const processed = useMemo(() => {
  return heavyTransform(data);
}, [data]);
@Reviewer
この `heavyTransform` が実際に高コストであるという裏付け(件数、計算量)があるかを確認してください。処理内容が軽量であれば、`useMemo` は読みにくさを増すだけで、逆効果となります。
const visibleItems = useMemo(() => filterVisible(items), [items]);
@Reviewer
このような軽量処理に `useMemo` を適用することは、読み手に「何か特別な理由があるのでは?」という誤読を与えかねません。明示的な意図がある場合を除き、通常の処理で十分です。

まとめ:useMemoは“最適化”ではなく“最終手段”

useMemoは「書いたら速くなる魔法」ではありません。レビューでは、以下の観点からその必要性を常に問い直すことが大切です。

useMemoレビューのチェックリスト
  • 再計算が高コストであることが明確か?
  • 処理の重さと再実行頻度に合理性があるか?
  • 依存配列の管理がメンテナンスコストを上げていないか?
  • 可読性を犠牲にするほどのメリットがあるか?

useMemoがあることで意図が曖昧になり、逆にコード全体の設計意図が見えなくなることもあります。レビューでは常に「これは本当に必要か?」という根本的な問いをぶつけることが、実装品質を保つ鍵になります。