One of the goals of the Jellyvision development team is to contribute back to the open source community. To this end, we have open sourced our creatively named js-library-extensions project on Github, a collection of extensions to popular open source JavaScript libraries and frameworks.

At the moment it is very Backbone-centric, as that is what we are using to develop a number of our projects. Backbone is a very powerful library that we like for its simplicity and flexibility. It provides just enough of what you need to structure a complex web app, but it does so without locking you into patterns that might not fit your project as it grows.

We chose not to use a pre-made set of Backbone extensions such as Marionette or Thorax because we wanted to keep things simple — the smaller base you start out with, the more easily you can shape it into exactly what you need for your project.  Additionally, we don’t want to create a larger app payload than is necessary.

Whether you choose an existing set of extensions or roll your own, Backbone can be easily extended and tailored to suit your project. This is what Jellyvision has done for ALEX, and we hope that others will find our additions useful.

Cleanup methods

One thing that Backbone doesn’t provide is a robust memory management solution. This is critical for long-lived single page apps (think Gmail), but luckily it’s not as hard to build as you might think. The approach that we’re taking is to conventionally call a cleanup method on an object when it is no longer needed. Our general-purpose cleanup method is Backbone.dispose. This method does several things:

  • It removes any Backbone event listeners (which we only bind to with listenTo to keep modules self-contained)
  • It removes any event listeners and removes any associated elements from the DOM
  • It deletes all properties from the object being disposed

We may end up enhancing this over time, but right now it gives us the functionality that we need. It’s important for general-purpose utility methods like this to be light and simple, because they get used a frequently.

In addition to Backbone.dispose, we also define Backbone.View.prototype.teardown. This method should be called when a View’s Model is destroyed, followed by a call to Backbone.dispose:

var ExtendedView = Backbone.View.extend({
  initialize: function () {
    this.listenTo(this.model, 'destroy', _.bind(this.teardown));
  }

  ,teardown: function () {
    Backbone.View.prototype.teardown.call(this);
    Backbone.dispose(this);
  }
});

The nice thing about this pattern is that it allows you to easily inject custom cleanup code before the object is disposed — for example, firing an event or calling a cleanup method on another component.

Async methods

Jellyvision is building a single page web app that never unloads during use. However, it constantly loads and unloads mini-apps as modules. These modules can perform arbitrary logic, which can include asynchronous operations such as setTimeout calls and AJAX requests. Here’s the catch: by the time a module’s asynchronous operation completes, the module may have already been unloaded. Any remaining callback functions will cause runtime errors and unpredictable behavior. The solution is to cancel any asynchronous operations when the module is unloaded. Rather than handle this explicitly for every async operation in each module, we abstracted it into reusable Backbone extensions:

setTimeout and clearTimeout are wrappers for their JavaScript-standard counterparts, and ajax is a wrapper for jQuery.ajax. The idea is to call these methods from within a Backbone View so that the operation can automatically be cancelled during teardown  when the View is no longer needed.

More to come!

As we create more useful utilities that can be generalized into reusable components, we hope to share them in the js-library-extensions repo. Watch the project on Github to stay on top of the latest developments!




Tagged with: