A utility for tracking notifications in knockout js

We’re developing a web site at the moment with a relatively liberal usage of javascript – not quite a single page application, but it has some fairly advanced controls. Knockout is used to provide us with MVVM capabiities and naturally we use jQuery for interacting with the DOM or server.

Unfortunately the majority of my company’s clients are still on IE 8, even though Microsoft is due to stop supporting it in the near future. We are testing the site using the XP mode virtual machine provided by Microsoft and seeing some unflattering performance issues. On a page that hosts a complex, interactive table, IE can take the CPU to 100% – making it unresponsive. Worryingly, this causes a warning dialog to appear asking the user if they want to stop executing the script. I thought I’d seen the last of those messages years ago, but corporate browser policies are like time machines!

I wasn’t sure what was causing it, so I started work on a project to track the frequency that observables in my view model notified subscribers of changes.

The project is split into two components: a node server that keeps track of reported subscriptions and displays a graph of notifications over time; and a client side script that watches your view model and reports to the server.

The client side script I’m referring to is in tracker.js. To set it up it’s called with a function to report results to. The function takes as arguments the results, a success callback function and a failure callback function. For convenience one is provided in jQueryReporter.js that uses jQuery to send the results via jsonp to another website (we’ll get to that later). The function that’s returned needs to be called with the view model object as an argument. The returned object can be queried over the page’s lifetime by calling getCount() on it.

The script uses a recursive function to traverse the properties of an object, adding information about any observables to an array. The visited objects are tagged with a string property to prevent traversing them again in a circular reference. Unfortunately for reasons I have yet to understand this doesn’t solve it completely and can result in a stack overflow. To mitigate this I simply added a maximum recursion limit, which is inelegant, but effective.

Another highlight is the use of an automatically-executing function within the for(i in o){..} loop. An earlier naive approach omitted this, which meant that each iteration of the loop referred to the same subscriberToken variable. The solution is to introduce a closure over the body of the loop, so that each iteration gets a fresh context (so to speak). This catches many people out, and I’m sure it won’t be the last time for me either.

The server uses express and jshtml to render the html. Jshtml was selected because there were a lot of choices and it was the most familiar considering my asp.net/razor background. The chart that’s shown is provided by dev express and I must say they’ve done a fantastic job! Their graphs are feature rich, beautiful and customisable. They also provide a raft of demos to help getting started.

I’ll write a few more posts about developing the server code, especially the jsonp and SSL aspects, which I had difficulty with.

Leave a comment