Knockout.js 在半大型数据集下非常慢 [英] Knockout.js incredibly slow under semi-large datasets

查看:25
本文介绍了Knockout.js 在半大型数据集下非常慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用 Knockout.js(一直想尝试一下,但现在我终于有了借口!) - 但是,在将表绑定到相对一小部分数据(大约 400 行左右).

I'm just getting started with Knockout.js (always wanted to try it out, but now I finally have an excuse!) - However, I'm running into some really bad performance problems when binding a table to a relatively small set of data (around 400 rows or so).

在我的模型中,我有以下代码:

In my model, I have the following code:

this.projects = ko.observableArray( [] ); //Bind to empty array at startup

this.loadData = function (data) //Called when AJAX method returns
{
   for(var i = 0; i < data.length; i++)
   {
      this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
   }
};

问题是上面的 for 循环大约需要 30 秒左右,大约有 400 行.但是,如果我将代码更改为:

The issue is the for loop above takes about 30 seconds or so with around 400 rows. However, if I change the code to:

this.loadData = function (data)
{
   var testArray = []; //<-- Plain ol' Javascript array
   for(var i = 0; i < data.length; i++)
   {
      testArray.push(new ResultRow(data[i]));
   }
};

然后 for 循环在眨眼间完成.换句话说,Knockout 的 observableArray 对象的 push 方法非常慢.

Then the for loop completes in the blink of an eye. In other words, the push method of Knockout's observableArray object is incredibly slow.

这是我的模板:

<tbody data-bind="foreach: projects">
    <tr>
       <td data-bind="text: code"></td>
       <td><a data-bind="projlink: key, text: projname"></td>
       <td data-bind="text: request"></td>
       <td data-bind="text: stage"></td>
       <td data-bind="text: type"></td>
       <td data-bind="text: launch"></td>
       <td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
    </tr>
</tbody>

我的问题:

  1. 这是将我的数据(来自 AJAX 方法)绑定到可观察集合的正确方法吗?
  2. 我希望 push 每次调用它时都会进行一些繁重的重新计算,例如重建绑定的 DOM 对象.有没有办法延迟重新计算,或者一次推送我的所有项目?
  1. Is this the right way to bind my data (which comes from an AJAX method) to an observable collection?
  2. I expect push is doing some heavy re-calc every time I call it, such as maybe rebuilding bound DOM objects. Is there a way to either delay this recalc, or perhaps push in all my items at once?

如果需要,我可以添加更多代码,但我很确定这是相关的.在大多数情况下,我只是在关注网站上的淘汰赛教程.

I can add more code if needed, but I'm pretty sure this is what's relevant. For the most part I was just following Knockout tutorials from the site.

更新:

根据以下建议,我更新了代码:

Per the advice below, I've updated my code:

this.loadData = function (data)
{
   var mappedData = $.map(data, function (item) { return new ResultRow(item) });
   this.projects(mappedData);
};

然而,this.projects() 对于 400 行仍然需要大约 10 秒.我承认我不确定 没有 Knockout(只是通过 DOM 添加行)会多快,但我感觉它会比 10 秒快得多.

However, this.projects() still takes about 10 seconds for 400 rows. I do admit I'm not sure how fast this would be without Knockout (just adding rows through the DOM), but I have a feeling it would be much faster than 10 seconds.

更新 2:

根据下面的其他建议,我给了 jQuery.tmpl 一个镜头(由 KnockOut 原生支持),这个模板引擎将在 3 秒多一点的时间内绘制大约 400 行.这似乎是最好的方法,但没有一种可以在滚动时动态加载更多数据的解决方案.

Per other advice below, I gave jQuery.tmpl a shot (which is natively supported by KnockOut), and this templating engine will draw around 400 rows in just over 3 seconds. This seems like the best approach, short of a solution that would dynamically load in more data as you scroll.

推荐答案

如评论中所建议.

Knockout 有它自己的与 (foreach, with) 绑定相关联的原生模板引擎.它还支持其他模板引擎,即 jquery.tmpl.阅读此处了解更多详情.我还没有对不同的引擎进行过任何基准测试,所以不知道它是否会有所帮助.阅读您之前的评论,在 IE7 中您可能很难获得您所追求的性能.

Knockout has it's own native template engine associated with the (foreach, with) bindings. It also supports other template engines, namely jquery.tmpl. Read here for more details. I haven't done any benchmarking with different engines so don't know if it will help. Reading your previous comment, in IE7 you may struggle to get the performance that you are after.

顺便说一句,KO 支持任何 js 模板引擎,如果有人为它编写了适配器.您可能想尝试其他人,因为 jquery tmpl 将被 JsRender 取代.

As an aside, KO supports any js templating engine, if someone has written the adapter for it that is. You may want to try others out there as jquery tmpl is due to be replaced by JsRender.

这篇关于Knockout.js 在半大型数据集下非常慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆