Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing backbone zombie views

Note: we are using backbone 1.0.0

I am relatively new to Backbone, and was going to through some of the code a ex co-worker wrote. Rather than copy pasting stuff blindly, I wanted to understand how he did things, and that's when I started wondering about the best way to handle zombie views.

var view = new editItemView({ model: this.model });
    this.ui.editItemPopup.html(view.render().el).modal({ modalOverflow: true });

This creates an instance of view and pops it up in a boostrap modal. The model has Save Changes, Cancel & Delete buttons. We will look at the clean work that is done on Save changes and delete.

onDelete: function() {
    this.stopListening(this.model);
    this.$el.parent().modal('hide');
    this.$el.remove();
},
onApplyChangesClick: function () {
    this.stopListening(this.model);
    this.close();
},
close: function () {
    this.$el.parent().modal('hide');
}

As far as I can tell, this code won't discard the view. And if I were to add another listener to the aforementioned view

this.listenTo(this.model.AnotherItem, 'change', this.doSomething);

and then trigger the change event on this.model.AnotherItem, this.doSomething will still fire. Correct?

I did some reading on Zombie views prior to posting this question. http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

And based on that article wouldn't I be better off if I just did

 onDelete: function() {
    this.close()
},
onApplyChangesClick: function () {
    this.close();
},
close: function () {
    this.$el.parent().modal('hide');
    this.remove();
}

his.remove() will automatically call stopListening and also remove the dom element(Same as this.$el.remove)

The article that I posted also uses this.unbind()

this.unbind()will unbind any events that our view triggers directly – that is, anytime we may have calledthis.trigger(…)` from within our view, in order to have our view raise an event.

Is that still necessary in Backbone 1.0.0 (or latest version)? The article is 3 years old, so I was wondering and I couldn't find any mention of view.unbind in backbone documentation. The documentation mentions that unbind is an alias of off. So should I be doing

this.remove();
this.off();
like image 899
iDesi Avatar asked Oct 21 '14 20:10

iDesi


1 Answers

Ok, first off let me state the obvious: a few zombie views here or there are not going to cause you any problems. All any given zombie view will do is eat up a small amount of memory and then go away when the user hits refresh or navigates away. So, if you're a little sloppy about cleaning up your references in general things will still work fine. Where you will run in to problems is when you have a lot of zombie views, say because you rendered a 20x100 table where every cell has its own View.

Now, to truly understand how to avoid zombie views you have to understand how memory works in Javascript. I encourage you to read more about that elsewhere, but here's the cliff notes version: anything you "stop using" will get cleaned up by the browser's garbage collector, and since the garbage collector can't tell exactly when you "stop using" something it actually goes by whether or not that thing has any references to it on other objects.

This is where event bindings come in to play, because they can create references that prevent a view from being garbage collected. One of the features of Backbone is that it handles cleaning up these bindings if they are made as part of a Backbone.View's initialization (ie. the events you put in an events property of the View class). So if you remove a View's element from the page, it will get garbage collected ...

... unless it has some other reference to it, like another object that uses it, or an event binding that you created using jQuery. So, as long as your Views don't have any other references you are correct: simply removing the element will be enough. But if you do have any other references, you will need to clean them up or else the View won't get garbage collected and will become a zombie view.

like image 51
machineghost Avatar answered Oct 29 '22 16:10

machineghost