Knockout Dependency Tracking

Computed values only depend on the observables they reference.

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<script id="tmpl-1" type="text/html">
    <div>Template 12</div>
    <div data-bind="text: dependency1"></div>
</script>

<strong>Dependency1</strong>
<p id="pd1" data-bind="text: dependency1"></p>
<strong>Dependency2</strong>
<p data-bind="text: dependency2"></p>
<strong>Computed (depends on Dependency1)</strong>
<p data-bind="text: computed"></p>
<strong>Template 1</strong>
<div data-bind="template: 'tmpl-1'"></div>

<button data-bind="click: changeDependency1">Change Dependency1</button>
<button data-bind="click: changeDependency2">Change Dependency2</button>

JavaScript

// Intercept calls to binding provider and when applying bindings
//
// Proof of concept
//
(function (ko) {
    var snapshot = false;
    var debug = {
        log: function () {
            var time = "",
                now  = new Date().getTime();
            if (snapshot) {
                time = "+" + (now - snapshot).toString();
            }            
            
            if (console.log) {
                console.log("[profiler]" + time, arguments);
            }
            
            snapshot = now;
        }
    };
    var super_instance    = ko.bindingProvider['instance'],
        super_applyBindings = ko.applyBindings,
        super_getBindings = ko.bindingProvider['instance']['getBindings'],
        init = true;
    
    var fnSubscriptionChange = function (key, model) {
        return function (newValue) {
            // A value has changed outside of initialization
            init = false;
            
            // Log it
            debug.log("CHANGE: (" + key + "), Updating subscriptions: " + 
                       (model[key]['getSubscriptionsCount']() - 1).toString());
        };
    };
    
    ko.applyBindings = function (viewModel, node) {
        snapshot = new Date().getTime();
        
        debug.log("ATTACH:", viewModel);
        for (var key in viewModel) {
            if (viewModel[key]['subscribe']) {
                debug.log("SUBSCRIBE: " + key);
                viewModel[key]['subscribe'](fnSubscriptionChange(key, viewModel));
            }
        }
        
        return super_applyBindings.apply(this, arguments);
    };
    
    ko.bindingProvider['instance']['getBindings'] = function (node, bindingContext) {
        var bindings = super_getBindings.apply(super_instance, [node, bindingContext]),
            viewModel = bindingContext['$root'],
            observables = [],
            properties = [];
        
        if (init) {
            return bindings;
        }
        
        for (var property in...