Ich habe eine ziemlich gute Javascript-Codebase (mit react / redux, aber keine jquery) für eine Webapp, die ich gerade erstelle, und mir ist aufgefallen, dass beim wiederholten Öffnen und Schließen eines bestimmten Panels in der Benutzeroberfläche die Anzahl von Laut Chrooms Performance-Timeline werden die Hörer immer größer.
Das Diagramm sieht folgendermaßen aus:
Ich habe den Leistungsmonitor des Chroms für ein oder zwei Minuten laufen lassen, während die Seite im Leerlauf war (kurz nach dem Öffnen / Schließen des Panels), in der Hoffnung, dass die Hörer Müll gesammelt bekommen, aber nicht. Ich habe während dieses Prozesses zu anderen Tabs gewechselt und hoffe auch, dass die Hörer Müll gesammelt bekommen, wenn der Tab im Hintergrund ist, aber leider nicht.
Ich vermute daher, dass einige Listener registriert werden, die nie nicht registriert werden.
Dies führt mich zu zwei Hauptfragen:
%Vor%
Auch nach dem Auskommentieren aller Code-Teile, die dazu führen, dass diese console.trace ausgeführt wird (siehe # 1), so dass die console.trace nicht mehr beim Öffnen / Schließen des Panels gedruckt wird, bemerke ich dasselbe Erhöhen Sie die Anzahl der Listener im Leistungsdiagramm. Etwas anderes bewirkt, dass die Zuhörer zunehmen. Ich verstehe, dass es andere Möglichkeiten gibt, Listener hinzuzufügen, aber mir ist nicht klar, wie man all diese Möglichkeiten abfängt oder sie im Debugger von Chrome so einloggt, dass ich weiß, welcher Code dafür verantwortlich ist .
Bearbeiten : - Auf den Vorschlag von Cowbert in den Kommentaren habe ich diese Seite angeschaut: Ссылка
Ich habe dann folgende Funktion ausgeführt:
%Vor%Ich führe diese Funktion aus, nachdem ich das Panel einige Male geöffnet / geschlossen habe, aber die Zahl "numListeners" ändert sich nicht. Wenn sich die numListeners-Zahl ändert, wäre ich in der Lage, die Ergebnisse vor / nach dem Öffnen / Schließen des Panels zu vergleichen, um herauszufinden, welches Element hat den zusätzlichen Ereignis-Listener registriert, aber numListeners ändert sich leider nicht.
Es gibt auch eine monitorEvents () API, die auf Ссылка beschrieben ist, aber die Funktion Aufruf erfordert, dass Sie ein DOM-Element angeben, das Sie überwachen möchten. In dieser Situation bin ich mir nicht sicher, welches DOM-Element das Extra hat Ich bin mir nicht sicher, wie der Aufruf von monitorEvents () mir wirklich helfen wird. Ich könnte es an alle DOM-Elemente anhängen, ähnlich wie ich es getan habe geschrieben die printListenerCount Funktion oben, aber ich nehme an, ich würde auf ein ähnliches Problem stoßen, dass ich mit printListenerCount () - Aus welchem Grund auch immer, es handelt sich nicht um die fraglichen Zuhörer.
Weitere Anmerkungen:
Dies ist eine etwas komplizierte reaktive (vorwirkende, technisch) basierte Anwendung. Wie die meisten reactjs-basierten Apps werden Komponenten im laufenden Betrieb eingehängt / ausgehängt (in das DOM eingefügt und daraus entfernt). Ich finde, dass dies "streunende Event-Handler-Registrierungen" wie dieses ein bisschen schwierig ausfindig zu machen. Also, was ich wirklich hoffe, ist ein allgemeiner Debugging-Ratschlag, wie man "Stray Event Handler" in großen / komplexen Projekten wie diesem ausfindig macht. Als C-Programmierer würde ich gdb
öffnen und einen Haltepunkt für alles setzen, was die "Listeners" -Nummer im Leistungsdiagramm möglicherweise erhöhen könnte. Ich bin mir nicht sicher, ob es ein Analogon in der JavaScript-Welt gibt, und selbst wenn es dort ist, bin ich mir einfach nicht sicher, wie ich es machen soll. Jeder Rat würde sehr geschätzt werden!
Danke für Ihre Kommentare, alle. Ich habe das herausgefunden.
Von meinem OP:
- Ist meine Hypothese, dass Zuhörer hinzugefügt werden und niemals ungebunden werden, sinnvoll, oder kann ich noch mehr tun, um diesen Verdacht zu bestätigen?
Es stellt sich heraus, dass die Antwort auf diese Frage lautet: Die Hypothese ist nicht sinnvoll. Die Zuhörer hatten einfach noch keine Chance, Müll zu sammeln. Es kann etwas länger dauern, als Sie vielleicht denken.
So habe ich es herausgefunden: Ich habe nicht erkannt, dass es während der Aufnahme einer Performance-Timeline möglich ist, eine Speicherbereinigung zu erzwingen, indem Sie auf der Registerkarte Leistung auf das Papierkorb-Symbol klicken (dieselbe Registerkarte zum Starten der Timeline-Aufzeichnung). Durch Klicken auf dieses Symbol nach wiederholtem Schließen / Öffnen des UI-Bedienfelds verschwanden die zusätzlichen Zuhörer vollständig. Die Grafik sieht nun so aus, dass die Dips Momente sind, in denen ich auf das Papierkorb-Symbol geklickt habe:
Offensichtlich ist es einfach nicht genug Zeit, die Registerkarte zu erstellen und ein paar Minuten zu warten, wie ich im OP erwähnt habe. Es braucht etwas mehr Zeit als das.
Ich war mir nicht bewusst, dass ich mit dem Mülleimer-Symbol Müll manuell sammeln kann, wenn ich das OP schreibe ... Ich empfehle dringend, es zu benutzen, bevor es irgendwelche wilden Gansjagden gibt, die auf den ersten Blick wie eine Aufführung aussehen könnten Problem.
Tags und Links javascript