DOM节点泄漏与淘汰赛foreach

时间:2014-08-29 09:54:31

标签: javascript knockout.js dns resource-leak

我一直看到IE8和IE9中的内存使用随着时间的推移逐渐增加,我们的一个网络应用程序。经过一些调查后,它似乎与Knockout中的foreach绑定有关。我编写了一个简化的JSFiddle,在这里强调了这个问题:http://jsfiddle.net/jfbbprkh/1/

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

在Chrome中运行此功能,您可以看到在垃圾收集器启动之前,DOM使用率逐渐增加,在IE8和IE9中,这种情况并未发生,DOM使用率不断上升和上升。我也通过sIEve略微改变了这一点,这也凸显了这个问题。

在小提琴中,您可以使用复选框禁用foreach绑定,在Chrome中使用配置文件工具时,您会看到DOM使用情况保持稳定,因此我怀疑这与{{{{ 1}}绑定以及它添加和删除DOM元素的方式。我猜测这些元素仍然附加了一些事件处理程序,这就是为什么它们没有被正确清理的原因。

我也试过更换'嵌套' foreach有一个模板(不知道如何在小提琴中这样做)但它仍然表现出相同的问题。

所以问题是 - 我做错了什么,或者这是Knockout的真正错误?

注意:

  • 时间戳是为了显示正在发生的事情(我们在真正的应用中确实有类似的事情)。
  • 我们必须支持至少IE8,这反过来意味着JQuery 1.9x

1 个答案:

答案 0 :(得分:0)

我发现,如果你使用嵌套模型进行此类事情,内存泄漏就不会成为问题。这样,“状态”不会设置为可观察的,只是“状态”中的属性。

尝试类似

的内容
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/