Search code examples
javascriptbackbone.js

Do I need to destroy a Backbone Collection?


If I create a new Collection instance in Backbone do I need to care about removing it?

This is not about unbinding / stopListeningTo events bound to models/collections by Views when I remove views.

This case is that I may be creating multiple collections and passing them to a view multiple times. Each view is cleanly removed and any callbacks it bound to the collection are removed, but the collection itself is not.

I am not sure if, once the view which was instantiated with a collection is removed, whether JavaScript's garbage collection will just remove the collection - since it is no longer referenced by anything?

E.g. in the following. If changePage is called multiple times (the user flicks back and forth between two pages) each time I create a new collection called pageCollection. This is passed to a new instance of OtherView. Each time OtherView will be removed and any callbacks it attached to the collection removed. But not pageCollection itself.

In this case can I rely on JavaScript to remove pageCollection since, with the view gone, it is no longer referenced? Or - should I keep track of it and remove it?

app = {};

MyCollection = Backbone.Collection.extend({

    pagination: function() {
        return this.slice(0,19); //e.g. first 20 items
    }

}}

app.myCollection = new MyCollection();
app.myCollection.fetch();


MyView = Backbone.View.extend({

    changePage: function(page) {

        var pagedModels = app.myCollection.pagination();
        //I'll get one of these every time changePage is called
        var pagedCollection = new MyCollection(pagedModels);
        //use pageCollection to render the view e.g.
        var thumbsView = new OtherView({collection: pagedCollection}); 
       //not shown - use a 'region controller' to render this view
       //this will dispose of the last instance of OtherView and 
       //callbacks it attached to the collection
    }

})

Solution

  • The only thing that keeps a reference to the collection is the OtherView instance. You just need to make sure that no references to the view exist. The garbage collector will collect it when it deems appropriate.

    The view's element in the DOM will prevent it from being collected by the garbage collector. So, as you know already, calling remove on the view or manually unbinding everything (events from jQuery, Backbone, and native in addition to any references) is necessary.

    The models, when added to a collection, automatically keep a reference to the collection if model.collection isn't set already. So if they came from another collection, the models won't get the new collection and all is fine, just keep that in mind as it could cause a problem someday.

    [...] can I rely on JavaScript to remove pageCollection [...]

    I would say yes because anyway, a Backbone collection doesn't have a delete function. With JavaScript, you don't really need to keep track of objects and explicitly delete them. You need to keep track of the references and remove them.

    It's good to research the possible memory leaks problem in advance, but it's also best not to fall into the infinite hole of premature optimization. When you'll get a leak where you can't find the source, or just don't understand how to fix, come back to SO and ask about that.