私はビルドしているWebアプリケーションのかなり良いサイズのjavascript(react/reduxではjqueryはありません)コードベースを持っていますが、UI内の特定のパネルを繰り返し開いて閉じると、リスナーの数Chromeのパフォーマンスのタイムラインに沿って増加し続けています。アイドル(ちょうど開封後/パネル束を閉じる)、おそらくことを期待して、私が座っページとの良好な分または2のためのChromeのパフォーマンスモニタの実行を許可してい イベントリスナーの追加先を追跡するにはどうすればよいですか?
:
グラフは次のようになりますリスナーはガベージコレクションを行いますが、そうではありません。私はこのプロセス中に他のタブに切り替えました。また、タブが背景になっているときにリスナーがガベージコレクションを取得することを期待していましたが、残念ながらそうではありません。
したがって、登録されていない一部のリスナーは登録されていないと思われます。
これは、主に2つの質問に私をリード:
- 私の仮説は、リスナーが追加取得され、決して 結合していないが賢明なようだ、またはそれ以上があることを私は にこの疑惑を確認するために行うことができますか?
- 私の疑惑が正しいと仮定すると、 は、イベントリスナーがあるコードを追跡するのにどうすればいいですか? が追加されていますか?私はすでに以下を試しました:
- 問題のパネルを開くコードを見て、それがリスナーを追加する場所を見て、それらの部分をコメントアウトしてパフォーマンスグラフに変更があるかどうかを調べます。変更はありません。その後、(参照#このconsole.traceを実行させるすべてのコード部分をコメントアウト、でもこれをやった後
var f = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, fn, capture) {
this.f = f;
this.f(type, fn, capture);
console.trace("Added event listener on" + type);
}
:そのようにaddEventListenerプロトタイプをオーバーライド
編集: -
function printListenerCount() {
var eles = document.getElementsByTagName("*");
var numListeners = 0;
for (idx in eles) { let listeners = getEventListeners(eles[idx]);
for(eIdx in listeners)
{
numListeners += listeners[eIdx].length;
}
console.log("ele", eles[idx], "listeners", getEventListeners(eles[idx]));
}
console.log("numListeners", numListeners)
}
が、私はこれを実行します: https://developers.google.com/web/tools/chrome-devtools/console/events
は、私は、次の関数を作っ コメントでcowbertの提案では、私は、このページを見ていましたパネルを数回開いたり閉じたりした後に機能しますが、残念ながら "numListeners"の数字は変わりません。 numListenersの図が変更された場合は、パネルの開閉の前後で結果を比較して、追加のイベントリスナーが登録されている要素が見つかったパネルを閉じることができますが、残念ながらnumListenersは変更されません。
https://developers.google.com/web/tools/chrome-devtools/console/eventsに記載されているmonitorEvents()APIもありますが、関数 を呼び出すには、監視するDOM要素を指定する必要があります。このような状況では、どのDOM要素に余分な リスナーがあるのかわからないので、monitorEvents()呼び出しが実際にどのように役立つのかよく分かりません。上記のprintListenerCount関数を に書き込んだのと同様に、すべてのDOM要素にアタッチすることができますが、私はprintListenerCount()で何が起こったのか、同様の問題に遭遇していると推測します。 問題のリスナーを説明します。
その他の注記: これはやや複雑な反応です(技術的にプレアクトな)アプリケーションです。ほとんどの反応系ベースのアプリケーションと同様に、コンポーネントはオンザフライでマウント/アンマウント(DOMへの挿入/削除)されます。私はこれがちょっとトリッキーな "迷子イベントハンドラ登録"を追跡することを発見しています。だから、私が本当に望んでいるのは、このような大規模なプロジェクトや複雑なプロジェクトの "Strayイベントハンドラ"を追跡する方法に関する一般的なデバッグアドバイスです。 Cプログラマとして、私はgdb
を開き、パフォーマンスグラフの "リスナー"番号を増加させる可能性のあるすべてにブレークポイントを設定します。私はJavaScriptの世界でそのアナログのアナログがあるかどうかは分かりません。たとえそれがあっても、それをどうやって行うのか分かりません。どんなアドバイスも大歓迎です!
chromeのmonitorEvents()APIを見てみましたか? https://developers.google.com/web/tools/chrome-devtools/console/events – cowbert
ありがとう、私はそれを見て、私のOPにメモを追加しました。 – Andrew
コード内のaddEventListenerのすべてのインスタンスを検索し、それらにブレークポイントを置くことができます。あなたが試してみる前に誰かが同じことをしない限り、プロトタイプの交換で得たものと大きく異なるべきではありません... – jcaron