mag = (function(mag) {
  
  var render = {
    roots: [],
    templates: {},
    cache: {}
  }
  
  var unloaders = [],
    cached = [],
    pendingRequests = 0

    function callView(elementClone, module, i) {
      var args = module.getArgs(i)

      var mod = module.modules[i]
      var controller = module.controllers[i]

      // var controllerConstructor = mod.controller.$original || mod.controller
      // var controller = controllerConstructor === cached.controllerConstructor ? cached.controller : new(mod.controller || function() {})

      mod.view(elementClone, controller)

      // if (controller.onunload) unloaders.push({
      //   controller: controller,
      //   handler: controller.onunload
      // })
    }
  render.callConfigs = function(configs) {
    //for (var i = 0, len = configs.length; i < len; i++) configs[i]()
  }
  render.redraw = function(module, fill, WatchJS) {
    module = module || render.module || {}
    console.time('Mag.JS:render')
    this.fun || (this.fun = debounce(function() {
      var prev
      for (var i = 0, root; root = render.roots[i]; i++) {
        if (module.controllers[i]) {
          var elementClone = module.elements[i]

          callView(elementClone, module, i)
          var args = module.getArgs(i)

          WatchJS.watch(args[0], debounce(function(ele, i, module, prop, type, newVal, oldVal) {
            console.time('Mag.JS:re-render')
            var args = module.getArgs(i)

            // check if data changed
            if (prev !== JSON.stringify(args[0])) {
              callView(ele, module, i)
              fill.fill(ele, args[0])
              WatchJS.noMore = true
              render.callConfigs(fill.configs)
              prev = JSON.stringify(args[0])
            }
            console.timeEnd('Mag.JS:re-render')
          }.bind(null, elementClone, i, module)))

          fill.fill(elementClone, args[0])
          render.callConfigs(fill.configs)
          prev = JSON.stringify(args[0])
        }
      }
      console.timeEnd("MagnumJS:init")
      console.timeEnd('Mag.JS:render')
    }))
    this.fun()
  }

  var $cancelAnimationFrame = window.cancelAnimationFrame || window.clearTimeout;
  var $requestAnimationFrame = window.requestAnimationFrame || window.setTimeout;

  var debounce = function(fn, threshhold) {
    var lastRedrawCallTime, FRAME_BUDGET = threshhold || 16,
      deferTimer

    return function() {
      if (+new Date - lastRedrawCallTime > FRAME_BUDGET || $requestAnimationFrame === window.requestAnimationFrame) {
        // hold on to it
        if (deferTimer > 0) $cancelAnimationFrame(deferTimer)

        deferTimer = $requestAnimationFrame(function() {
          lastRedrawCallTime = +new Date
          fn.apply(this, arguments);
        }, FRAME_BUDGET);
      } else {
        lastRedrawCallTime = +new Date
        fn.apply(this, arguments);
      }
    }
  }

  mag.render = render
  return mag
  
}(window.mag || {}))

@@ -1,12 +1,16 @@
+var 
 mag = (funct
@@ -20,18 +20,16 @@
 (mag) %7B%0A
-  
 %0A  var r
@@ -90,18 +90,16 @@
  %7B%7D%0A  %7D%0A
-  
 %0A  var u
@@ -841,24 +841,41 @@
 gs%5Bi%5D()%0A  %7D%0A
+  var cache = %5B%5D%0A
   render.red
@@ -961,42 +961,8 @@
  %7B%7D%0A
-    console.time('Mag.JS:render')%0A
     
@@ -1017,20 +1017,143 @@
     var 
-prev
+redrawing = false%0A%0A      if (redrawing) return%0A      redrawing = true%0A      var prev%0A      var marker = '__' + new Date + '__'%0A
 %0A      f
@@ -1285,25 +1285,24 @@
 elements%5Bi%5D%0A
-%0A
           ca
@@ -1304,77 +1304,321 @@
    c
-allView(elementClone, module, i)%0A          var args = module.getArgs(
+onsole.time('Mag.JS:render:' + elementClone.id)%0A%0A          // prevent infinite recursion%0A          if (marker in elementClone) return%0A%0A          var args = module.getArgs(i)%0A%0A          if (cache%5Bi%5D && cache%5Bi%5D===JSON.stringify(args%5B0%5D)) %7B%0A            continue%0A          %7D%0A          callView(elementClone, module, 
 i)%0A%0A
@@ -1688,34 +1688,16 @@
 le, 
-prop, type, newVal, oldVal
+changeId
 ) %7B%0A
@@ -1730,33 +1730,43 @@
 Mag.JS:re-render
-'
+:' + ele.id
 )%0A            va
@@ -1846,20 +1846,24 @@
     if (
-prev
+cache%5Bi%5D
  !== JSO
@@ -2097,32 +2097,75 @@
 )%0A            %7D%0A
+            %0A            redrawing = false%0A
             cons
@@ -2189,25 +2189,35 @@
 JS:re-render
-'
+:' + ele.id
 )%0A          
@@ -2345,36 +2345,40 @@
 figs)%0A          
-prev
+cache%5Bi%5D
  = JSON.stringif
@@ -2380,32 +2380,160 @@
 ingify(args%5B0%5D)%0A
+          redrawing = false%0A          elementClone%5Bmarker%5D = true%0A          console.timeEnd('Mag.JS:render:' + elementClone.id)%0A
         %7D%0A      
@@ -2577,47 +2577,8 @@
 t%22)%0A
-      console.timeEnd('Mag.JS:render')%0A
     
@@ -3423,18 +3423,16 @@
 urn mag%0A
-  
 %0A%7D(windo

Update render.js