Cleaning after Knockout

29 בינואר 2013

Using KnockoutJS is really fun. You set some data-bind attributes on your HTML and KnockoutJS does the magic of binding it to a JavaScript object (A.K.A, view model)

An important fact that most of us are missing is that Knockout holds some internal data structure to manage its magic. Basically, every time you call ko.applyBindings a new management record is added to KO internal representation.

This means that your view model is being held by some global data managed by KO. So in case you create and destroy HTML dynamically using JavaScript the view model is not cleaned up by the browser garbage collector which eventually harts your application performance and stability.

Consider the following scenario,

  1. An HTML template was downloaded from the server and is held inside the browser memory (as a normal string)
  2. You use jQuery to clone the template and create an HTML element out of it
  3. You use KO to bind the newly created HTML element to a JavaScript object (view model)
  4. You destroy the HTML element when it is not needed any more

I hope you agree that this kind of manipulation is quite common for single page application

The problem, as I mentioned before is that destroying the HTML element is not enough. As result of using KO applyBindings mechanism KO is holding some global data which indirectly contains a reference to your view model.

To see this issue in action, open the attached sample and perform the following

  1. Take a heap snapshot using Chrome developer tools
  2. Click Create, Bind and then Destroy (do not click Unbind)
  3. Take another snapshot
  4. Ask Chrome to perform comparison of the two snapshots

Untitled

You will then noticed that an object of type ViewModel was created but was not collected by the garbage collector

Now, run the same scenario but this time click Create, Bind, Unbind and then Destroy

Untitled

As you can see, this time a ViewModel object was created and destroyed by the garbage collector.

So, what did the “Unbind” button do? Short answer: ko.cleanNode

To summarize, you should consider using ko.cleanNode before destroying an HTML element. Else, you end up with memory leaks !

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*