Knockout.js消耗太多内存

Att*_*Kun 5 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>
Run Code Online (Sandbox Code Playgroud)

使用此代码:

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());
});
Run Code Online (Sandbox Code Playgroud)

(也看到这个jsfiddle)

我觉得Firefox使用的私有字节增加了大约50-100 MByte.

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

<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>
Run Code Online (Sandbox Code Playgroud)

使用此代码:

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());
});
Run Code Online (Sandbox Code Playgroud)

(也看到这个jsfiddle)

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

RP *_*yer 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();
});
Run Code Online (Sandbox Code Playgroud)

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

原始样本的内存使用量似乎异常高.我认为foreach逻辑中可能存在一些可能有所帮助的优化,但这将需要/将需要更多的研究.