Prefilling Backbone model data

by Andy Appleton

The Backbone docs suggest that you should bootstrap data into your page on load. This allows the application to be responsive and ready to use as soon as the JavaScript is loaded. This is not always possible though – for example if the app does not have any kind of server side templating or if it interacts with an external API. (DailyJS has a good example of this kind of application).

In this case the application can seem slow to start as it first loads the JavaScript and then makes one or many API calls to populate the interface with data. Caching can help to a degree but this does not allow for new data to be fetched.

Cache Prefilling

I have a plugin called Backbone fetch cache which provides an in-memory and localStorage cache for Backbone’s fetch method. I’ve recently added a prefill option which will return cached data immediately (where available) but still make the background API request.

This is really nice because it allows us to present the user with a working interface immediately and then update the data in place as the AJAX requests complete. If you’ve ever used the Instagram iPhone app you might notice that it does something similar, presenting an interface with the last available data whilst it makes background API calls to get the latest.

Use

The initial cache hit triggers all of the same events (add, reset, change etc) as an actual call to fetch, but the success callback is not fired until the AJAX call completes. Instead a new callback is available, prefillSuccess:

myModel.fetch({
  prefill: true,
  prefillSuccess: someCallback, // Fires when the cache hit happens
  success: anotherCallback // Fires after the AJAX call
});

If you prefer working with promises, the call to fetch also returns an instance of jQuery’s $.Deferred. A progress event is triggered when the cache hit occurs and the promise is resolved when the AJAX call completes:

var modelPromise = myModel.fetch({ prefill: true });
modelPromise.progress(someCallback); // Fires when the cache hit happens
modelPromise.done(anotherCallback); // Fires after the AJAX call

All in all I think this is a pretty nice solution to the problem of a slow initial page load for a single page JS application. As always the code and tests are available on GitHub.