1

我已经看到 IE8 和 IE9 中的内存使用量随着我们的 Web 应用程序之一逐渐增加。经过一番调查,它似乎与foreachKnockout 中的绑定有关。我已经编译了一个简化的 JSFiddle,在这里突出了这个问题:http: //jsfiddle.net/jfbbprkh/1/

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

在 Chrome 中运行此程序,您可以看到 DOM 使用量在垃圾收集器启动之前逐渐上升,在 IE8 和 IE9 中不会发生这种情况,DOM 使用量一直在上升和上升。我还通过 sIEve 对此进行了一些细微的修改,这也突出了这个问题。

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

我也尝试过用foreach模板替换“嵌套”(不知道如何在小提琴中做到这一点),但它仍然表现出同样的问题。

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

笔记:

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

1 回答 1

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/

于 2014-08-30T12:55:26.290 回答