Speicherleck beim wiederholten Anwenden von d3-Übergang

8

Ich habe eine SVG-Karte und ein Intervall, das Daten abfragt und die Farben auf der Karte entsprechend aktualisiert. Das alles funktioniert gut, es sei denn, ich benutze einen Übergang, um zu der neuen Farbe zu blenden. Dann frisst die Registerkarte langsam mehr und mehr Speicher auf, bis es abstürzt.

Ich habe ein vereinfachtes Beispiel erstellt, das dasselbe Verhalten zeigt:

%Vor%

Zypern

Ich habe es in Chromium (49) und Firefox (45) unter Linux versucht. Es scheint schneller zu explodieren, aber es ist ein Problem für beide. In beiden erscheint es nicht im Speicher-Profiler, sondern etwa: Speicher zeigt an, dass der Tab wächst.

Aus der Dokumentation geht hervor, dass das Hinzufügen eines Übergangs zu einer Auswahl jeden vorherigen Übergang mit demselben Namen ersetzt (einschließlich für einen leeren Namen), aber meine Hypothese ist, dass die zum Implementieren des Übergangs erstellten Funktionen nicht wirklich verworfen werden . Aber ich habe es nicht geschafft, auf sie zuzugehen, um das zu bestätigen oder das Problem zu umgehen.

Also, eine zweiteilige Frage:

  1. Ist das eine korrekte Verwendung von d3-Übergängen, oder gibt es einen korrektiveren Weg, um das zu tun, wofür ich vorgehe?
  2. Wenn ich den Übergang richtig verwende, wie kann ich verhindern, dass Speicher ausgelaufen wird?

BEARBEITEN:

  1. Nach dem Kommentar von Blindman67 habe ich es geändert, um setTimeout zu verwenden und etwas kleiner zu sein. Das Original, das ich zu simulieren versuche, ist kleiner und langsamer, aber es dauert Stunden, bis es definitiv größer wird, also habe ich versucht, das zu beschleunigen. Diese Version scheint immer noch zu wachsen, zumindest für mich auf Chrom.
  2. Ich bin so weit, zu beobachten, dass d3_selectionPrototype.transition jedes Mal ein neues d3_transition mit einer inkrementierenden ID erstellt, aber das ist in Ordnung, wenn der alte Müll gesammelt wird. Und ich kann immer noch nicht darauf hinweisen, ob und warum es beibehalten wird.
Klaas 16.05.2016, 03:48
quelle

1 Antwort

0

Ich bin ziemlich sicher, dass es dieses Stück genau hier machen muss:

%Vor%

Jedes Mal, wenn Sie die Funktion shuffleColors() aufrufen, ruft sie sich selbst erneut auf und erstellt im Wesentlichen eine Rekursionsschleife ohne einen Basisfall. Der Grund, warum es nicht sofort explodiert, ist, dass jeder Aufruf der Funktion 1000ms verzögert hat. Ich denke jedoch, dass es länger dauert, bis squares.interrupt().transition().duration(500).style("fill", color); fertig ist, als für setTimeout() , um aufgerufen zu werden. Also, obwohl Sie es alle 1000ms aufrufen, könnte es in gewisser Weise stapeln, da einige Farbänderungen mehr Zeit für die Verarbeitung benötigen.

Obwohl es technisch nicht so sein sollte, zu wissen, wie asynchrones JavaScript ist, kann es eine Rolle haben. Ich würde stattdessen vorschlagen, dies zu tun und die Ergebnisse zu berichten:

%Vor%

Sie können auch clearInterval(timer) aufrufen, wenn Sie dies irgendwann tun möchten. setInterval() wurde genau aus dem Grund erstellt, weil Sie setTimeout() implementiert haben.

Bearbeiten: Dies funktioniert möglicherweise nicht vollständig, da Sie möglicherweise noch warten müssen, bis die Farbänderung abgeschlossen ist, es wäre jedoch zumindest ein sauberer Ansatz. Sie können möglicherweise eine Art wait() -Funktion implementieren, um auf den Abschluss der Farbänderung zu warten.

Obwohl Vektor (SVG) -Bilder leicht sind, ist die Verarbeitungsmenge, die erforderlich ist, um Farben oder Ähnliches ständig zu ändern, im Vergleich zur Decodierung eines JPEG-Bildes enorm.

Sie können bessere Ergebnisse erzielen, wenn Sie die ursprüngliche Bildgröße viel kleiner machen und dann auf Ihre Auflösung erweitern. Du könntest ein 100x100-Canvas-SVG machen und es auf 2000x2000 oder so erweitern, so dass es kein so großes Bild zeichnen muss.

    
Dark Swordsman 15.11.2017 03:39
quelle

Tags und Links