【ツール活用|実務向け】Chrome DevToolsの「Event Listeners」タブでメモリリークを防ぐ:SPA開発の必須デバッグ術

導入

モダンなフロントエンド開発、特にReactやVueなどのSPA(Single Page Application)において、「なぜか画面を遷移してもイベントが発火し続ける」「メモリ使用量が時間とともに増えていく」といった問題に直面したことはありませんか?その原因の多くは、不要になったイベントリスナーの削除漏れです。Chrome DevToolsの「Event Listeners」タブを使いこなすことで、DOMに紐付いたイベントを可視化し、こうした厄介なバグを効率的に特定・解消する方法を解説します。

基礎知識

イベントリスナーとは、ボタンクリックやスクロール、キー入力などの特定の「イベント」が発生した際に実行される関数のことです。通常、addEventListenerで登録しますが、不要になった際にはremoveEventListenerで明示的に削除する必要があります。
しかし、SPAではコンポーネントが破棄される際、この「削除処理」を忘れると、関数がメモリ上に残り続けます(メモリリーク)。これが積み重なると、アプリケーションの動作が重くなったり、予期せぬタイミングで関数が実行されたりする原因となります。

実装/解決策

Chrome DevToolsを開き、「Elements」パネルを選択します。右側のサイドバーにある「Event Listeners」タブをクリックしてください。ここには、選択したDOM要素に登録されているすべてのイベントハンドラが表示されます。
注目すべきは「Framework listeners」のチェックボックスです。これにチェックを入れると、ライブラリ内部のラッパー関数ではなく、実際に記述したソースコードまでトレースできるようになります。リストを展開すると、そのイベントが登録されているファイル名と行番号が表示されるため、即座に修正対象を特定できます。

サンプルプログラム

以下のコードは、イベントリスナーの削除を忘れた際のメモリリークの例と、その修正案です。

// 悪い例:コンポーネント破棄時に削除処理がない
const button = document.querySelector(‘#my-button’);
function onClick() { console.log(‘Clicked!’); }
button.addEventListener(‘click’, onClick);
// このままでは、ページ遷移してもイベントがメモリに残る

// 良い例:適切に削除(removeEventListener)を行う
const button = document.querySelector(‘#my-button’);
const onClick = () => console.log(‘Clicked!’);

button.addEventListener(‘click’, onClick);

// コンポーネントの破棄(アンマウント)処理内で実行
function cleanup() {
// 登録時と全く同じ関数参照を指定して削除する
button.removeEventListener(‘click’, onClick);
console.log(‘リスナーを削除しました’);
}

応用・注意点

現場で陥りやすい罠として、「無名関数(アロー関数)を直接渡して登録している」ケースがあります。
button.addEventListener(‘click’, () => { … });
このように書くと、後からremoveEventListenerで削除しようとしても、関数への参照が保持されていないため削除ができません。必ず関数を変数として定義し、その変数を渡すようにしてください。
また、特定のDOM要素だけでなく、windowやdocumentにイベントを登録している場合は、DevToolsの「Event Listeners」タブで「Ancestors(祖先要素)」を確認し、グローバル領域にゴミが溜まっていないかを定期的にチェックする習慣をつけることを強く推奨します。

コメント

タイトルとURLをコピーしました