Knockout.js非常缓慢地预示着

时间:2012-08-01 17:50:28

标签: javascript knockout.js

我正在尝试使用模板创建一个简单的标记。类似的东西:

<div class="list" data-bind="template: {name: 'mytemplate', data: someData}"></div>

<script id="mytemplate">
  <div class="item" data-bind="text: someText"></div>
</script>

它工作得非常好,但是如果我需要使用这个模板渲染很多div,那么它将非常慢。创建每个div后的Knockout将其添加到文档中。但是,如果我做这样的事情:

el = document.createElement("div");
applyBindings(myModel, el);

(div.list).innerHTML = el.innerHTML

它工作得更快但不方便。

也许Knockout有一些内置功能可用于创建一组元素,然后将该组添加到文档中?

2 个答案:

答案 0 :(得分:6)

听起来KO正在使用您添加的每个DIV操作DOM。 DOM遍历很昂贵,会降低页面的渲染速度。在KO Github下有一个未解决的问题:https://github.com/SteveSanderson/knockout/issues/248

在我看来,Knockout目前还没有完成处理大型foreach数据集的任务。 Chrome上的性能不错(因为Chrome很棒),但在Internet Explorer上却很糟糕(在旧的IE上更糟糕):http://jsfiddle.net/StarcounterJack/FgSCw/

不要使用Knockout,而是尝试手动方法:首先在内存中创建DIV,然后将它们一次性插入到DOM中。这是你在document.createElement()的第二个例子中所做的。使用jQuery,你可以这样做:

var newDiv = $("<div>my new div</div>");
var newDiv2 = $("<div>my new div2</div>");
newDiv.append(newDiv2);
$('body').append(newDiv); //only this last step traverses the DOM

对于模板,我更喜欢使用Mustache.js,使用John Resig的<head><script type="text/templates"> template inclusion trick加载模板,并通过我自己的JavaScript手动处理渲染。您可以更好地控制元素的呈现方式,并在遇到类似现在的性能问题时尝试不同的方法。

答案 1 :(得分:2)

现在最好的解决方案可能是knockout-fast-foreach plugin

它具有O(1)插入和删除功能,以及其他功能,使其显着快速(即比你自己更容易做到的速度快)。

在KO 3.5(或3.6)中取代目前的foreach绑定是一个强有力的竞争者。