エージェント向け Chrome DevTools を使用すると、コーディング エージェントがアプリケーションのクライアントサイドのメモリリーク(JavaScript や WebAssembly など)を分析して修正できます。ヒープ スナップショットの収集と分析を自動化することで、エージェントは適切にガベージ コレクションされていないオブジェクトを特定し、ターゲットを絞ったコード リファクタリングを提案できます。
Agentic Workflows では、コーディング エージェントがさまざまなアプリケーション状態のスナップショットを複数取得し、専用の分析ツールを使用します。
メモリ デバッグツールを有効にする
デフォルトでは、エージェント向け Chrome DevTools は take_heapsnapshot ツールのみを公開します。ヒープ スナップショットを分析するツール(compare_heapsnapshots、get_heapsnapshot_summary、get_heapsnapshot_retaining_paths など)は、--memoryDebugging フラグを指定してサーバーを起動した場合にのみ使用できます。このフラグがないと、エージェントはスナップショットをキャプチャできますが、分析できません。
メモリ デバッグツールを有効にするには、サーバー引数に --memoryDebugging を追加します。
"args": ["chrome-devtools-mcp@latest", "--memoryDebugging"]
その他のオプションについては、構成をご覧ください。
一般的なメモリリークのパターン
メモリ分析では、次のような一般的なリークパターンの検出に重点を置いています。
- クリアされていないイベント リスナー: グローバル オブジェクト(
windowやdocumentなど)にアタッチされたイベント リスナー。ガベージ コレクションを妨げます。 - 切り離された DOM ノード: ドキュメント ツリーから削除されたが、JavaScript 変数によって参照されているノード。
- 意図しないグローバル変数: 適切なスコープなしで宣言され、メモリに永久に残る変数。
- クロージャ: 独自のスコープで大きなオブジェクトへの参照を意図せず保持するクロージャ。
- 無制限のデータ構造: キャッシュに使用されるデータ構造。制限なく増加します。
メモリ分析に関する考慮事項
メモリ分析を使用する場合は、次の点に注意してください。
未加工のスナップショットを直接読み取らない: エージェントに未加工の
.heapsnapshotファイルを直接読み取らせないでください。これらは大きすぎて、コンテキストの上限を超えています。メモリリークのデバッグ スキルは、これらのファイルを読み取らないようにエージェントに明示的に指示します。3 つのスナップショット手法: リークを確実に検出するには、通常、エージェントは 3 つのスナップショットをキャプチャする必要があります。アクション前のベースライン、アクション後のターゲット、アクションを元に戻した後の最終スナップショットです。タイマー(
setTimeout)やアニメーション(requestAnimationFrame)によってトリガーされるアクションなど、ユーザー操作なしで発生するアクションもあり、元に戻す手順が必要ない場合もあります。タイマー(
setTimeout)やアニメーション(requestAnimationFrame)によってトリガーされるアクションなど、一部のアクションはユーザー操作なしで発生し、メモリ使用量が増加する可能性があります。修正前に確認する: エージェントの検出結果を常に確認して、提案されたアクションがアプリのロジックに適用可能で正しいことを確認します。たとえば、エージェントに参照を無効にするよう指示する前に、デタッチされたノードが意図的なキャッシュの一部であるかどうかを確認します。
メモリリーク分析のユースケース
エージェントに、タイマーやユーザー操作などの繰り返し操作中にメモリをプロファイリングするよう指示します。スナップショットを手動で取得して手動で差分を比較するのではなく、エージェントにプロファイリングを指示します。これらのワークフローを使用して、メモリ分析をデバッグ プロセスに統合します。
注: エージェントの実行手順は、潜在的な動作の例です。エージェントの動作が異なる場合があります。
ナビゲーション中にクリアされていないイベント リスナーを検出する
シングルページ アプリケーション(SPA)では、コンポーネントのマウント解除後にデベロッパーがグローバル イベント リスナーを削除し忘れると、メモリリークが発生することがよくあります。ビュー間の移動時にメモリが正しく解放されることを確認するようエージェントに指示できます。
プロンプトの例:
Navigate from the home page to the dashboard and back to the home page. Use the take_heapsnapshot tool to check if we have any uncleared event listeners causing memory leaks.
エージェントの実行例: エージェントは、ホームページでベースラインのヒープ スナップショットを取得し、ダッシュボードに移動して、ホームページに戻り、最終的なスナップショットを取得します。次に、内部分析ツールを使用してスナップショットを評価し、window オブジェクトにアタッチされた scroll リスナーがクリアされていないことを検出して、コンポーネントのクリーンアップ関数で removeEventListener を呼び出す特定のコードを提供します。
UI コンポーネント内のデタッチされた DOM ノードを特定する
モーダル、ドロップダウン、複雑な UI コンポーネントは、DOM から削除された後も JavaScript 変数で参照が保持されていると、切り離された DOM ノードが残ることがよくあります。
プロンプトの例:
Open the user settings modal and close it 5 times. Analyze the heap snapshots and tell me if there are any detached DOM nodes left behind. If there are, ask me if they are intentional before writing a fix.
エージェントの実行例: エージェントは、必要なベースライン、ターゲット、最終スナップショットを収集しながら、設定モーダルを操作します。分析の結果、Detached HTMLDivElement というラベルの付いたオブジェクトがいくつか増えていることがわかります。エージェントは、検出結果を報告し、DOM 参照を保持する変数を null に設定するコードを変更する前に、確認を求めます。
継続的なインタラクションで上限のないキャッシュを見つける
無限スクロールや継続的なデータ取得などの機能では、基盤となる配列やマップが上限なしで無限に増大すると、メモリリークが発生する可能性があります。
プロンプトの例:
Scroll down the infinite feed list to load more items three times. Check if our LRU cache is unbounded and leaking memory, and suggest a fix.
エージェントの実行例: エージェントがスクロール前後のメモリ状態を分析します。無制限に増加する大きな配列を意図せずキャプチャするクロージャを特定します。エージェントは、オブジェクトのライフサイクルに関連付けられたデータにキャッシュ保存の制限を実装するか、WeakMap を使用して、適切なガベージ コレクションを可能にすることを提案します。
バックグラウンド プロセスのメモリリークをデバッグする
アニメーション タイマーとバックグラウンド タイマーは、明示的なユーザー操作なしでメモリリークを引き起こす可能性があります。エージェントにメモリの増加をモニタリングするように指示して、これらのプロセスのメモリリークを検出できます。
プロンプトの例:
Explore this canvas application and monitor memory usage. Help me determine areas of improvement around reusing objects and textures.
エージェントの実行例: エージェントがキャンバス アプリケーションを探索し、定期的にスナップショットを自動的に取得して、メモリ使用量を継続的にモニタリングします。ヒープを分析し、レンダリング ループが新しい WebGL メッシュを配列にプッシュするたびに、以前のメッシュをガベージ コレクションしていないことを特定し、オブジェクトの再利用に関する最適化を提案します。