Mam dość dobry rozmiar javascript (z reżimem/redux ale nie jquery) dla budowanej przeze mnie aplikacji webowej i zauważyłem, że kiedy wielokrotnie otwieram i zamykam pewien panel w interfejsie, liczba słuchaczy według czasu działania Chrome stale rośnie.Jak mogę znaleźć miejsce, w którym dodaje się program nasłuchujący zdarzenia?
I pozwoliły uruchomić monitor wydajności Chrome za dobrą minutę lub dwie z strony siedzi bezczynnie (tuż po otwarciu/zamknięciu panelu pęczek), mając nadzieję, że może słuchacze otrzymają śmieci zebrane, ale tak nie jest. W trakcie tego procesu przełączyłem się na inne zakładki, mając również nadzieję, że słuchacze otrzymają śmieci zebrane, gdy zakładka jest w tle, ale niestety tak nie jest.
Podejrzewam, że niektórzy słuchacze są rejestrowani, a nigdy nie są rejestrowani.
To prowadzi mnie do dwóch podstawowych pytań:
- Czy moja hipoteza, że słuchacze są dodawane uzyskiwanie i nigdy niezwiązany wydaje się sensowne, czy jest tam jeszcze mogę zrobić, by potwierdzić te podejrzenia?
- Zakładając, że moje podejrzenie jest poprawne, jak najlepiej odejść w sprawie śledzenia kodu, w którym znajduje się obiekt nasłuchiwania zdarzeń? . Próbowałem już:
- Sprawdzono kod, który jest odpowiedzialny za otwarcie danego panelu, sprawdzając, gdzie dodaje on wszystkich słuchaczy, i komentując te fragmenty, aby zobaczyć, czy są jakieś zmiany w wykresie wydajności. Nie ma zmiany.
- Zastąpiona prototyp addEventListener tak:
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);
}
Nawet po zrobieniu tego, czym komentując wszystkie fragmenty kodu, które powodują ten console.trace do wykonania (patrz # 1) tak, że plik console.trace nie jest już drukowany na otwartym/zamkniętym panelu, zauważam ten sam wzrost w słuchaczach na wykresie wydajności. Coś innego powoduje wzrost słuchaczy. Rozumiem, że istnieją inne sposoby dodawania słuchaczy, ale nie jest dla mnie jasne, jak przechwycić wszystkie te możliwości lub spowodować, że będą one logowane w debugerze Chrome w taki sposób, żebym mógł stwierdzić, który kod jest odpowiedzialny za ich dodanie .
Edit: - Na sugestię cowbert w komentarzach, wziąłem do obejrzenia tej strony: https://developers.google.com/web/tools/chrome-devtools/console/events
Potem złożył następujące funkcję:
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)
}
I wykonanie tego funkcja po kilkukrotnym otwarciu/zamknięciu panelu, ale niestety liczba "numListeners" się nie zmienia. Jeśli liczba numListeners zmieniłaby się, byłbym w stanie zmienić wyniki przed/po otwarciu/zamknięciu panelu, aby odkryć, który element ma zarejestrowany dodatkowy detektor zdarzeń, ale niestety numListeners się nie zmienia.
Istnieje również funkcja API monitorEvents() opisana w https://developers.google.com/web/tools/chrome-devtools/console/events, ale funkcja wymaga określenia elementu DOM, który ma być monitorowany. W tej sytuacji nie jestem pewien, który element DOM ma dodatkowe detektory , więc nie jestem pewien, w jaki sposób wywołanie monitorEvents() naprawdę mi pomoże. Mogłem dołączyć go do wszystkich elementów DOM, podobnie jak miałem napisałem powyższą funkcję printListenerCount, ale przypuszczam, że napotkałem podobny problem, który napotkałem z printListenerCount() - z jakiegokolwiek powodu, to nie jest rozliczanie danego słuchacza (ów).
Inne uwagi: Jest to dość skomplikowana aplikacja reagjs (preact, technicznie). Podobnie jak większość aplikacji opartych na responsjach, komponenty są montowane/odłączane (wstawiane i usuwane z DOM) w locie. Zauważyłem, że to sprawia, że śledzenie "bezpańskich rejestratorów zdarzeń" jest trochę skomplikowane. Tak naprawdę mam nadzieję, że jest kilka ogólnych porad dotyczących debugowania, jak wyśledzić "Zabłąkane programy obsługi zdarzeń" w dużych/złożonych projektach takich jak ten. Jako programista C, otworzę gdb
i ustawię punkt przerwania na wszystko, co może spowodować zwiększenie liczby "słuchaczy" na wykresie wydajności. Nie jestem pewien, czy istnieje analogia w świecie javascript, a nawet jeśli tam jest, po prostu nie jestem pewien, jak to zrobić. Każda rada byłaby doceniona!
Czy próbowałeś spojrzeć na API monitorEvents() w chrome? https://developers.google.com/web/tools/chrome-devtools/console/events – cowbert
Dzięki, przyjrzałem się temu i dodałem notatki do mojego OP. – Andrew
Możesz spróbować wyszukać wszystkie wystąpienia addEventListener w kodzie i umieścić na nich punkt przerwania. Nie powinno to być bardzo różne od tego, co otrzymałeś z prototypową wymianą, chyba że ktoś robi to samo, zanim to zrobisz ... – jcaron