16

Summary

Why is the following plunkr causing a memory leak every time $compile runs?

http://plnkr.co/edit/HhB4croPKuN5TP2NPqq6

Explanation to the code

I am writing a directive which sometimes needs to completely re-render its HTML. It does this by generating its template as a string, and then feeding that string to $compile, finally using jQuery to remove the old DOM and replace it with the newly rendered element.

Each time it does this, the application leaks several megabytes of memory, often crashing the browser. The Chrome heap snapshot shows a tree of detached DOM elements gets added each time, but the Plunkr for some reason does not have this issue (although it still leaks a lot).

What am I doing wrong that causes this memory leak?

"What? Generating a string template and re-compiling it? Why?"

This is clearly not the way Angular directives are meant to be written, I know. My first approach would be a combination of ng-repeats with other two-way binding. Unfortunately, this causes performance issues as the number of $watch-statements on the scope increases. For a bit of reasoning as to why I chose this approach, I give a small rant about it here: How does data binding work in AngularJS?

EDIT

I have been working on the plunk, and it no longer leaks memory. I'll keep this question around, in case anyone else finds it useful as a non-leaking method for re-compiling DOM.

Community
  • 1
  • 1
MW.
  • 12,550
  • 9
  • 36
  • 65
  • 4
    What was the issue? Were you not destroying the scope or unbinding an event? – Daniel Tabuenca Oct 30 '13 at 01:04
  • 2
    Yes and yes; those were the two issues. In my 'real' code we also had memory leaks in one of the third-party directives (tooltip in bootstrap-ui) which didn't release references to the dom elements, and also didn't remove jQuery event listeners when the scope was destroyed. But that specific error was never part of the plunk (took me a while to find it, though). – MW. Oct 30 '13 at 07:50
  • 1
    Please close this question or better yet - answer it explaining what was causing the leak and how it was fixed exactly and then accept the answer. – Benjamin Gruenbaum Dec 03 '13 at 14:09

1 Answers1

3

Answered it myself to make sure it doesn't crop up under "unanswered". I have been working on the plunk, and it no longer leaks memory. I'll keep this question around, in case anyone else finds it useful as a non-leaking method for re-compiling DOM.

MW.
  • 12,550
  • 9
  • 36
  • 65
  • So doing the following helped htmlElement.remove(); htmlElement = null; ? childScope.$on("$destroy", function () { htmlElement.off(); – bhantol Aug 01 '14 at 05:16