DOM节点漏洞与淘汰赛foreach

问题描述:

我一直在看到IE8和IE9中的内存使用量随着时间的推移逐渐增加与我们的一个Web应用程序。经过一番调查,它似乎与Knockout中的foreach绑定有关。我已编译了一个简化的JSFiddle,其中突出显示了此问题:http://jsfiddle.net/jfbbprkh/1/DOM节点漏洞与淘汰赛foreach

在实际应用程序中,模型从后端更新,状态每次都被覆盖。如果您翻转复选框

在Chrome中运行此功能,您可以在垃圾收集器投入使用之前逐渐看到DOM使用情况,在IE8和IE9中这种情况不会发生,DOM使用率会持续上升和上升。我也通过sIEve对此进行了细微的变化,这也突出了这个问题。

在拨弄你可以禁用foreach使用复选框结合,并使用Chrome的性能分析工具时,你会看到DOM使用保持稳定,因此为什么我怀疑这是关系到foreach结合,它的方式添加并删除DOM元素。我猜测元素有一些事件处理程序依然附着在它们上面,这就是为什么它们没有正确清理。

我也尝试用模板替换'嵌套'foreach(不知道如何在小提琴中这样做),但它仍然存在相同的问题。

所以问题是 - 我做错了什么或者这是一个真正的缺陷与Knockout?

注:

  • 时间戳在那里展示一些东西是怎么回事(我们确实有在真正的应用程序类似的)
  • 我们必须至少支持IE8这反过来又意味着JQuery的1.9倍
+0

你拨弄甚至不工作?我为你添加了ko和jQuery引用,所以请更新你的答案 - http://jsfiddle.net/jfbbprkh/1/ – 2014-08-29 11:53:58

+0

@PWKad对此表示歉意,当我提交链接时我确实检查了它,所以不知道发生了什么那里错了。 – baesp 2014-08-29 12:40:48

我发现如果你使用嵌套模型来处理这种事情,那么内存泄漏就变成了一个小问题。这样,“状态”不会设置为可观察的,只是“状态”内的属性。

尝试像这里

var status = { 
    Timestamp: ko.observable(), 
    Rows: ko.observableArray([]), 
    Update: function (updateValues) { 
     status.Timestamp(updateValues.Timestamp); 
     status.Rows(updateValues.Rows) 
    } 
} 

var model = { 
    EnableStatus: ko.observable(true), 
    Timestamp: ko.observable(), 
    Status: status, 

    Update: function() { 
     model.Timestamp(new Date()); 
     model.Status.Update({Timestamp: new Date(), 
      Rows: [{ 
       Name: "Row #0", 
       Value: Math.random() 
      }, { 
       Name: "Row #1", 
       Value: Math.random() 
      }, { 
       Name: "Row #2", 
       Value: Math.random() 
      }]}) 
    } 
}; 

$(document).ready(function() { 
    ko.applyBindings(model, $("#wrapper")[0]); 
    setInterval(model.Update, 1000); 
}); 

小提琴>>>http://jsfiddle.net/uv0ga3gn/

+0

谢谢你 - 我会给它一个,我应该也许已经说过模型正在被ko.mapping插件更新。所提供的模型实际上是真正应用程序中“顶级”模型中包含的许多模型之一,因此需要一点点重新思考才能完全实现。 – baesp 2014-09-02 07:39:52

+0

不幸的是,在Chrome和IE浏览器中似乎都漏出了DOM节点,并且有一个简单的例子。 – baesp 2014-09-02 07:49:16