Zombie Views and view.destroy()

74 views
Skip to first unread message

Peter Michaux

unread,
Jul 14, 2012, 12:02:30 PM7/14/12
to mari...@googlegroups.com
Zombie views are cause for memory and performance leaks in an MVC
application when a view is created, added to the DOM, removed from the
DOM, and discarded without proper cleanup. For example, take the
following code.

var model = new myApp.MyModel();
// create a view that observes the model
var view = new myApp.MyView(model);
// add the view to the page so the user can see it
var wrapperElement = document.getElementById('wrapper');
var viewRootElement = view.build();
wrapperElement.appendChild(viewRootElement);
// some time later, perhaps based on user activity, remove
// the view from the document so the user can no longer see it.
setTimeout(function() {
wrapperElement.removeChild(viewRootElement);
// loose our application reference to the view
view = null;
viewRootElement = null;
}, 1000);

During view creation, the view automatically subscribes to the model.
When the model fires a "change" event, the view's "update" method will
be called. This gives the view an opportunity to update the visible
representation of the model's changed data. This continues every time
the model changes until the view unsubscribes from the model.

In the above code, the view never unsubscribes from the model. Since
the application no longer has any references to any parts of the view
object, the view has become a zombie: it cannot be garbage collected
because the model has a reference to the view for the observer pattern
to work and the view obediently updates forever though no one is
watching. Memory and performance leaks.

To avoid zombie views, before your application looses its last
reference to a view that has been removed from the document you need
to call view.destroy(); which will unsubscribe the view from the
model. The setTimeout section of the above example needs just one more
line.

setTimeout(function() {
wrapperElement.removeChild(viewRootElement);
// unsubscribe the view from the model
view.destroy();
// loose our application reference to the view
view = null;
viewRootElement = null;
}, 1000);

With this extra line in place, the view is no longer referenced by the
model, the document, or your application code. The view stops updating
and can be garbage collected.
Reply all
Reply to author
Forward
0 new messages