【ITニュース解説】余計なuseMemoを1つ消したらtscが135秒高速化した話
2025年09月08日に「Zenn」が公開したITニュース「余計なuseMemoを1つ消したらtscが135秒高速化した話」について初心者にもわかりやすく解説しています。
ITニュース概要
React+TypeScript開発で、パフォーマンス最適化目的の`useMemo`が逆にビルドを遅くさせる事例が報告された。不要な`useMemo`を1つ削除した結果、TypeScriptのコンパイル時間が135秒も高速化。複雑な型推論を招く実装が原因と見られる。(120文字)
ITニュース解説
Webアプリケーション開発、特に大規模なプロジェクトにおいて、開発効率は非常に重要な要素となる。その効率を左右する一つが、プログラムのビルドやコンパイルにかかる時間だ。今回は、ReactとTypeScriptを用いたプロジェクトで、たった一つのコードを修正した結果、TypeScriptのコンパイル時間が146秒から11秒へと、実に135秒も短縮された事例について解説する。この現象は、パフォーマンス最適化の難しさと、問題解決への体系的なアプローチの重要性を示している。
まず、この問題を理解するために、いくつかの技術的な背景を説明する必要がある。TypeScriptは、JavaScriptに「静的な型」の概念を導入したプログラミング言語である。コードを実行する前に、変数や関数の引数がどのような型のデータを持つべきかを定義し、コンパイラがそのルールに違反していないかをチェックする。このチェックと、ブラウザが解釈できるJavaScriptコードへの変換処理を「コンパイル」と呼ぶ。このコンパイル時に行われる型のチェックが複雑になるほど、コンパイルにかかる時間は長くなる傾向がある。一方、Reactはユーザーインターフェースを構築するためのJavaScriptライブラリであり、その中で使われる「useMemo」はパフォーマンス最適化のための機能の一つだ。useMemoは、計算に時間のかかる処理の結果を一時的に保存(メモ化)しておき、入力値が変わらない限り再計算を行わずに保存した結果を再利用することで、アプリケーションの動作を高速化する役割を持つ。
今回問題が発生したプロジェクトでは、開発者がコードを少し変更するたびに、TypeScriptのコンパイルに146秒、つまり2分半近くも待たされるという深刻な状況に陥っていた。このような長い待ち時間は、思考の連続性を妨げ、開発者の生産性を著しく低下させる。開発チームはこの問題を解決するため、原因の調査を開始した。そして驚くべきことに、その原因はたった一行の、useMemoで囲まれたコードにあることが突き止められた。
問題となったコードは、あるオブジェクトのキーと値を入れ替える、という一見すると単純な処理であった。しかし、この処理がTypeScriptのコンパイラ、特に「型推論」の機能に想定外の重い負荷をかけていたと考えられる。型推論とは、開発者が明示的に型を記述しなくても、コンパイラがコードの文脈から自動的に変数の型を推測する便利な機能だ。問題のコードでは、オブジェクトのキーと値を動的に入れ替えることで、結果として生成される新しいオブジェクトの型が非常に複雑なものになっていた可能性がある。コンパイラは、その複雑な型を正確に推論しようと膨大な計算を行い、結果としてコンパイルプロセス全体が極端に遅くなってしまったのだ。本来、useMemoはアプリケーションの実行時のパフォーマンスを向上させるためのものだが、このケースでは、その内部で行われる処理が開発時のコンパイルパフォーマンスを劇的に悪化させるという、皮肉な結果を招いてしまった。
この事例で特に注目すべきは、広大なコードの中からどのようにして原因となる一行を特定したか、その問題解決のプロセスである。開発者はまず、パフォーマンスに影響を与えそうな複雑な型定義や、高度な型操作を行っている箇所に当たりをつけた。しかし、大規模なプロジェクトでは、そのような箇所は無数に存在する。そこで採用されたのが「二分探索」という古典的かつ効果的な手法だ。これは、問題の原因が含まれる可能性のある範囲を半分に絞り込む作業を繰り返すことで、効率的に原因箇所を特定するアプローチである。具体的には、コードベースの半分を一時的にコメントアウトし、コンパイル時間が短縮されるかを確認する。もし短縮されれば、原因はコメントアウトした部分にあり、変わらなければ残りの部分にあると判断できる。この作業を繰り返すことで、調査範囲を指数関数的に狭めていくことができる。
この地道で反復的な作業は、人間が手作業で行うには多大な労力を要する。そこで、このプロジェクトではAIコーディングエージェントが活用された。ファイル群を対象に二分探索を自動で実行するようAIに指示し、人間では時間のかかる検証プロセスを自動化することで、迅速に原因箇所を特定することに成功した。
この事例は、システムエンジニアを目指す者にとって多くの教訓を含んでいる。第一に、パフォーマンス最適化は諸刃の剣であるということだ。useMemoのような最適化手法は、その必要性や影響を深く理解せずに適用すると、かえって新たな問題を引き起こす可能性がある。「早すぎる最適化は諸悪の根源」という格言が示すように、まずはボトルネックを正確に特定し、慎重に適用することが求められる。第二に、TypeScriptの型システムは非常に強力である反面、その複雑さがコンパイルパフォーマンスに影響を与える可能性があることを認識する必要がある。特に、大規模なデータ構造を扱う際や、複雑な型操作を行う際には、コンパイル時間にも注意を払うべきだ。そして最後に、問題解決能力の重要性である。未知の問題に直面した際に、論理的に仮説を立て、二分探索のような体系的な手法で原因を切り分け、AIのような新しいツールを効果的に活用する能力は、現代のエンジニアにとって不可欠なスキルと言えるだろう。