CanJS部分是活绑定视图,部分不是



我正在构建一个包含数千个列表项且没有分页的数据网格。因此,可以理解的是,现场绑定的性能非常差。大约有20个列表项,没有任何滞后。

<thead>
    {{#each columns}}
        <tr><td can-click="sort">{{name}}</td></tr>
    {{/each}}
</thead>
<tbody>
    {{#each thousandsOfItems}}
        <tr><td>{{name}}</td></tr>
    {{/each}}
</tbody>

有没有一种方法可以让我的模板的一部分实时绑定,比如<thead>,但对<tbody>使用简单的字符串连接/注入?

编辑

我的方法可能是个问题。数以千计的静态<tr>可能也相当滞后。有人建议我在滚动页面时尝试添加/删除行。

我制作了一个JSPerf,在单列表中渲染4000行,您可以在这里查看:

http://jsperf.com/can-stache-table-render

这些实验的一些收获:

  • 没有现场绑定,您可以获得10倍的性能提升。不过,如果你需要的不止这些,你可能必须提高你的表现。

  • 当不实时绑定任何数据时,使用{{#each}}与仅使用{{#ThousandOfRows}}}相比,不会提高性能

  • 使用div而不是表行是我感兴趣的尝试,因为你可以更快地看到增量绘制(但实际上,所有这些都同步运行,UI会锁定,直到全部以这种方式绘制),但绘制整个表的速度要慢35%,最好避免。

基于此,我们能做些什么?

  • 对表格进行分页,或者更确切地说,绘制许多固定大小的表格,直到数据用完为止。第一个屏幕将快速渲染,其余屏幕将在您进行渲染时填充。使用setTimeout()绘制下一个表,以免锁定UI。

  • 使用实时绑定,但使用以下模式进行分页:

    var i=0; function loop() { while(i < source_list.length) { list_in_live_binding_context.push.apply( list_in_live_binding_context, source_list.splice(i, 20) ); i += 20; setTimeout(loop, 4); } }

  • 做前面两件事中的一件,但用微调器将结果隐藏在屏幕后面,直到渲染完成

  • 使用jquery ui可滚动(https://github.com/bseth99/jquery-ui-scrollable)要检测元素何时滚动到视图中,请使用Stache辅助对象仅在项目滚动到视图时渲染项目,但您需要首先保留空间。如果每一行都有复杂的渲染关联,这会很有帮助。您可以将细节延迟到必要时。

对不起,这不是一个简单的答案,但也不是一个容易的问题无论如何,HTH。

最新更新