We wanted to build a very simple event logger for our Backbone app to figure out what was causing long load times for an interaction that involved multiple round-trips to the server. We decided to use Backbone 0.9's built-in Events as a quick, lightweight way to track our custom events. While there may be more robust solutions for this use case, this helped us pinpoint the issue.
First, we need to fire the events:
Backbone.Events.trigger('Logger', {event: 'buttonClick', time: new Date()});
This triggers the "Logger" event, with an event named "buttonClick", and a datetime that's generated when the event is fired.
Next, we need to listen for the events. We use a single Backbone's Router and this seemed like the logical place to listen for the "Logger" events:
var myRouter = Backbone.Router.extend({ initialize: function(){ this.evLogger = {1 : {name : 'start_logger', time : new Date().getTime() }}; this.listenTo(Backbone.Events, 'Logger', this.logEvents); }, logEvents: function(data) { var newKey = _.size(this.evLogger) + 1; var time = data.time.getTime(); this.evLogger[newKey] = { name : data.event, time : time, delta : (time - this.evLogger[newKey - 1].time) }; } })
Upon loading of our app, we create an object called evLogger that will store all of the events, keyed on the order that they are received by the router, each of which has the event name and time. We listen for the "Logger" event with listenTo, and send each event to the logEvents function. Each new event is then added to this.evLogger with a time saved in milliseconds and a "delta" attribute, which is the difference in ms between the current event and the previous one.
The result is a simple hash of events that you can use to figure out where your bottlenecks are.
The event hash will only be as helpful as your event triggers. We experimented putting them before and after every call to the server or other Backbone view, collection, or model. We cut down on log events where there clearly wasn't a bottleneck, and added more granular log events where things were taking longer.
For a less quick and dirty solution, we could integrate into our custom baseView, which is just an extension of Backbone.View, and certain named methods on every view extending baseView could automatically log events without cluttering up the views themselves.