Können dynamisch geladen JavaScript entladen werden?
Schreibe ich eine web-Anwendung, die eine statische äußere "Schale" und einer dynamischen Inhalt". Der dynamische Inhalt Abschnitt hat viele updates, wie der Benutzer sich in dem system zurechtzufinden. Wenn Sie einen neuen content block geladen wird, kann es Optional auch das laden der JavaScript-Datei. Im Namen von good housekeeping, ich remove script blocks vom DOM für alte Inhalte blockiert, da das JavaScript wird nicht mehr benötigt.
Das problem kommt dann, wenn ich erkannte, dass, obwohl ich den entfernt <script>
- element aus dem DOM, die JavaScript, die zuvor bewertet wird, noch zur Ausführung zur Verfügung. Das macht Sinn, natürlich, aber ich bin besorgt, dass es möglicherweise einen Speicherverlust, wenn der Benutzer navigieren Sie zu einer Menge von verschiedenen Abschnitten.
Dann die Frage, sollte ich mir sorgen machen über diese situation? Wenn ja, gibt es eine Möglichkeit zu zwingen, den browser zu bereinigen veraltete JavaScript?
InformationsquelleAutor Andy | 2009-08-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
<theory>
Sie gehen könnte mit einer mehr Objekt-orientierten Ansatz und bauen das Modell in einer Weise, dass jeder block von javascript-Blöcke als eigene Objekte mit eigenen Methoden. Nach dem entladen stellen Sie einfach das Objekt aufnull
.</theory>
InformationsquelleAutor Sampson
(Das ist ziemlich off-the-Manschette.)
Speicher zu verwenden ist in der Tat ein Problem, das Sie besorgt sein müssen, mit in die aktuelle browser-state of the art, obwohl es sei denn, wir reden über ziemlich viel code, ich weiß nicht, die code-Größe ist das Problem (es ist in der Regel-DOM-Größe, und übrig gebliebene event-Handler).
Könnten Sie ein Muster für Ihre loadable Module, das würde es viel einfacher zu entladen, die Sie en Masse -- oder zumindest, um damit der browser weiß, es kann entladen.
Betrachten:
Definiert, dass eine Schließung, die die Funktionen enthält, die
foo
undbar
, die rufen sich gegenseitig in der üblichen Weise. Beachten Sie, dass code außerhalb von Funktionen wird sofort ausgeführt.Vorausgesetzt, Sie don ' T-pass aus, die Bezüge zu dem, was in die Schließung für alles, was außerhalb, dann Fenster.MyModule wird die einzige Referenz auf die Schließung und seinen Ausführungskontext. Entladen:
Sagt der JavaScript-Umgebung, die Sie nicht verwenden, die diese Eigenschaft nicht mehr, und macht alles, was es Referenzen für die garbage collection. Wann und ob diese Sammlung geschieht, ist offensichtlich von der Implementierung abhängig.
Beachten Sie, dass es wichtig sein wird, wenn Sie-hook event-Handler innerhalb des Moduls trennen Sie vor dem entladen. Könnten Sie tun, dass durch die Rückgabe einer Referenz auf eine Destruktor-Funktion anstelle der Haupt Verschluss:
Insulinspritzen ist dann:
InformationsquelleAutor T.J. Crowder
Beim speichern der ausgewerteten code in Namensräumen, wie z.B.:
"Befreien", die ganze Sache sollte so einfach wie Einstellung MYPP zu einem zufälligen Wert, ala
Dieses hängt von ab, dass es keine anderen Mittel der Verweis auf die variable, die ist nicht trivial
Nicht nur die variable selbst, sondern auch alle Verschlüsse, die möglicherweise erstellt werden, die Funktionen im inneren.
Ja, ich glaube, ich fühlte, dass impliziert wurde. Für diese arbeiten, es darf keine Verweise auf die weder die ANWENDUNG, noch alles drin. Und es gibt einige anspruchsvolle details, wenn es um ein Speicherleck, und IE. @Dykam: Kein Grund für nicht undefiniert, aber ich vermied es zu löschen, da ich nicht viel Erfahrung mit ihm, und eine "1" sollte das nicht ein riesiger Speicher belastet, was der OP tun kann.
InformationsquelleAutor Svend
Wie etwa das laden der JS-Dateien in einem iframe? Dann (in der Theorie, nie es selber getestet) können Sie den iframe aus dem DOM zu entfernen und den "Speicher" benutzt wird.
Denke ich... oder hoffe ich...
InformationsquelleAutor elcuco
Wenn Sie sind besorgt über memory-leaks, dann werden Sie wollen, stellen Sie sicher, dass es kein event-Handler im code entfernt werden soll bezogen auf die noch vorhandenen dom-Baum.
Kann es sein, dass Sie brauchen, um eine Liste aller event-Handler, die Ihrem code Hinzugefügt, und vor dem entladen, gehen durch und entfernen Sie den Ereignis-Handler.
Ich es noch nie getan haben, die Art und Weise, ich habe auch immer Angst, wenn ich mir zum entfernen von Knoten, es ist immer noch eine Referenz.
Hier ist ein guter Artikel über javascript memory-leaks:
http://javascript.crockford.com/memory/leak.html
InformationsquelleAutor James Black
JavaScript-Interpreter haben garbage-Kollektoren. In anderen Worten, wenn Sie nicht alles, es wird nicht halten Sie sich um.
Einer der Gründe, warum es gut ist, ist die Verwendung von JSON mit einer callback-Funktion (JSONP).
Beispiel, wenn Sie HTTP-Antwort für jeden JS:
Und wenn callback() nicht erstellen einen Verweis auf das JSON-Objekt übergeben als argument, es wird Müll gesammelt, nachdem die Funktion beendet ist.
Wenn Sie wirklich brauchen, um eine Referenz, dann müssen Sie wahrscheinlich, dass die Daten, um für einige Grund - sonst würden Sie/sollten Sie NICHT verwiesen wird es in den ersten Platz.
Erwähnten Methoden an namespace-Objekten erzeugt nur eine Referenz, die, wird beibehalten, bis der Referenzzähler geht auf 0. In anderen Worten, Sie haben zu verfolgen, jede Referenz und Sie später löschen, das kann hart sein, wenn Sie Verschlüsse und Referenzen aus den DOM herum. Nur eine Referenz wird, bleibt das Objekt im Speicher, und einige einfache Maßnahmen können die Erstellung von verweisen, ohne es zu merken.
InformationsquelleAutor bucabay
Nette Diskussion. Macht eine Menge Dinge. Ich habe noch eine Sorge, though.
Wenn ich bind Fenster.MyModule.bar() auf ein Ereignis, was passiert, wenn die Falle versehentlich ausgelöst, nachdem der Fenster.MyModule gelöscht wird? Für mich, der springende Punkt bei der Verwendung von Namensräumen und die Trennung von js in dynamisch geladenen Modulen ist zu vermeiden auslösende event-Handler Kreuz-Modul, indem Sie Fehler.
Zum Beispiel, wenn ich (entschuldigen Sie mein jQuery):
$('.einige-Klasse').klicken Sie auf ("Fenster".MyModule.bar);
Was passiert, wenn ich den löschen-Fenster.MyModule, laden Sie ein anderes Modul, und klicken Sie auf ein element, das versehentlich hat Sie eine Klasse namens einige-Klasse?
InformationsquelleAutor Miloš Rašić