Knockout.js消耗太多内存

时间:2011-06-27 20:20:11

标签: javascript performance jquery-templates knockout.js

我保持Process Explorer打开并检查firefox.exe进程的“Private Bytes”列。按下此示例中的“添加”按钮后:

<script id="tmplComment" type="text/x-jquery-tmpl">
    <div>
        <span>Comment:&nbsp;</span>
        <span data-bind="text: $data"></span>
    </div>
</script>    

<input type="button" id="btnAdd" value="Add"/>
<div id="Content" data-bind="template: {name: 'tmplComment', foreach: Comments}">        
</div>

使用此代码:

var vm = {Comments: ko.observableArray(["a", "b"])};
ko.applyBindings(vm);
$("#btnAdd").click(function()
{
    for(var i = 0; i<500; i++)
        vm.Comments.push(i.toString());
});

(另见this jsfiddle

我觉得Firefox占用的私有字节数增加了大约50-100 MB。

当我将它与缺乏依赖性跟踪的实现进行比较时,执行时间也相当长,给出了这个例子:

<script id="tmplComment" type="text/x-jquery-tmpl">
    <div>
        <span>Comment:&nbsp;</span>
        <span data-bind="text: $data"></span>
    </div>
</script>    

<input type="button" id="btnAdd" value="Add"/>
<div id="Content" data-bind="template: {name: 'tmplComment', foreach: Comments}">        
</div>

使用此代码:

var vm = {Comments: ko.observableArray(["a", "b"])};
ko.applyBindings(vm);
$("#btnAdd").click(function()
{
    for(var i = 0; i<500; i++)
        vm.Comments.push(i.toString());
});

(另见this jsfiddle

我的问题:使用Knockout.js时表现不佳还是我做错了什么?

2 个答案:

答案 0 :(得分:7)

暂时将内存问题暂时搁置,当前示例中的大部分时间都将花费在模板绑定的foreach选项中。确定数组中的哪些项被更改以确定如何有效地添加/删除DOM中的元素确实做了大量的工作。在你的情况下,这项工作已经完成了500次。

您可以通过以下方式获得更好的性能:

$("#btnAdd").click(function()
{
    var items = vm.Comments();
    for(var i = 0; i<500; i++) {
         items.push(i.toString());
    }

    vm.Comments.valueHasMutated();
});

这只是将项目推送到底层数组而不通知任何订阅者直到结束(调用observableArray上的push会将项目推送到底层数组并调用valueHasMutated)。

原始样本的内存使用率看起来非常高。我认为foreach逻辑中可能存在一些可能有所帮助的优化,但是这将会/将需要更多的研究。

答案 1 :(得分:0)

RP是正确的。看看:http://jsfiddle.net/uLkDP/32/

另一种非常类似的方法是:

$("#btnAdd").click(function()
{
    var a = ["a", "b"];
    for(var i = 0; i<500; i++)
        a.push(i);

    vm.Comments(a);
});

一个正在运行的例子:http://jsfiddle.net/uLkDP/30/

哦,还有一件事,我使用了进程黑客并监控了谷歌浏览器中的内存使用情况。 RP方法增加了大约4MB,另一个增加了大约8M。 它确实有意义,因为第二种方法使用两个数组。