(JS) Speicherfreigabe beim Entfernen von Elementen mit Events
jumini
- browser
EEE. Hallo zusammen,
ich arbeite aktuell an einem sehr JavaScript-lastigen Projekt.
Oft werden Inhalte per JavaScript eingefügt und anschließend mit diversen Events (z.B. onclick) versehen.
In der Regel entferne ich diese vor dem Löschen des betroffenen Elements.
Doch ist das überhaupt notwendig?
Übernehmen die großen Browser die Überprüfung auf (durch wegfallende Elemente) überflüssig werdende Events und geben den belegten Speicher automatisch frei?
Außerdem arbeite ich hauptsächlich mit der Prototype-Funktion "observe" - welche multiple Events erlaubt und daher vermutlich auf interne "cache"-Objekte für die Funktionen zurückgreift(?). Welcher Lösungsansatz wäre für die Vermeidung eines manuellen stopObserving()s zu empfehlen?
Gruß,
jumini
Oft werden Inhalte per JavaScript eingefügt und anschließend mit diversen Events (z.B. onclick) versehen.
In der Regel entferne ich diese vor dem Löschen des betroffenen Elements.
Doch ist das überhaupt notwendig?
Nicht in aktuellen JavaScript-Engines.
Wenn ein Element entfernt wird, kann der Browser auch alle Event-Handler entfernen, wenn keine anderen Referenzen darauf existieren.
In ältere Engines wie die von IE 6 und 7 hingegen können Event-Handler zu Memory-Leaks führen. Aber auch nur in bestimmten Fällen.
Bibliotheken sind aber auf diese Probleme eingestellt, d.h. das Event-Handling in PrototypeJS sollte keine Memory-Leaks erzeugen.
Übernehmen die großen Browser die Überprüfung auf (durch wegfallende Elemente) überflüssig werdende Events und geben den belegten Speicher automatisch frei?
Ja, sie haben einen ausgereiften Garbage-Collector.
Außerdem arbeite ich hauptsächlich mit der Prototype-Funktion "observe" - welche multiple Events erlaubt und daher vermutlich auf interne "cache"-Objekte für die Funktionen zurückgreift(?).
Wie meinst du das?
Prototype speichert zentral eine Liste der registrierten Handler, damit stopObserving möglich ist.
Im Internet Explorer wird diese Liste beim Abbauen der Seite automatisch gelöscht, da im IE 6 und 7 Memory-Leaks wegen fehlerhaftem Garbage-Collection auftreten könnten.
Welcher Lösungsansatz wäre für die Vermeidung eines manuellen stopObserving()s zu empfehlen?
Die Funktionsweise von Closures sollte dir bewusst sein. Damit hält die Engine Daten im Speicher, damit sie verfügbar bleiben. Lege Funktionen also sparsam und weise an, verwende ggf. Currying, um Einschließen und Konservieren von Objekten zu kontrollieren. Siehe dazu http://molily.de/weblog/closures-performance.
Was ältere IEs angeht, so bringt es wenig, im Vorhinein zu optimieren. PrototypeJS selbst ist diesbezüglich selbst schon optimiert. Es gibt viele Artikel und verschiedene Tools, um konkrete Memory-Leaks im eigenen Code aufzuspüren.
Wenn du keine merklichen Memory-Leaks wahrnimmst, dann besteht auch kein Problem und kein Bedarf, zu optimieren. Allerdings ist es natürlich keine schlechte Idee, wenn Komponenten sich »destruieren« können. Wenn du diese Struktur ohnehin schon hast, ergibt es Sinn, darin auch stopObserving bezüglich der registrierten Event-Handler aufzurufen. Ich glaube, dazu kann man Eventnamen mit einem Präfix versehen, um sie einer Gruppe zuzuordnen.
Mathias
Hallo Mathias,
Herzlichen Dank für die ausführliche Antwort.
Außerdem arbeite ich hauptsächlich mit der Prototype-Funktion "observe" - welche multiple Events erlaubt und daher vermutlich auf interne "cache"-Objekte für die Funktionen zurückgreift(?).
Wie meinst du das?
So:
Prototype speichert zentral eine Liste der registrierten Handler, damit stopObserving möglich ist.
Im Internet Explorer wird diese Liste beim Abbauen der Seite automatisch gelöscht.
Gut zu wissen! Ich werde Prototype in Zukunft etwas öfter selbst unter den Rock schauen.
Gruß,
jumini