我保持Process Explorer打开并检查firefox.exe进程的“Private Bytes”列。按下此示例中的“添加”按钮后:
<script id="tmplComment" type="text/x-jquery-tmpl">
<div>
<span>Comment: </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: </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时表现不佳还是我做错了什么?
答案 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。 它确实有意义,因为第二种方法使用两个数组。