【问题标题】:Knockout JS and large modelsKnockout JS 和大模型
【发布时间】:2012-06-16 00:47:54
【问题描述】:

我正在尝试找出使用 KnockoutJS 的最佳方法,我需要您的建议。

我的视图模型包含一组“文档”,每个文档都有一组“值”。 每个“文档”都使用以下模板呈现为单独的表格:

<div data-bind="foreach: Documents">
        <table data-bind="foreach: Values">
            <tr data-bind="foreach: $data">
                 <td data-bind="attr: {colspan: Colspan}">
                    <label data-bind="text: Label"></label>
                    <br />
                    <span data-bind="html: Value"></span>
                </td>
            </tr>
        </table>
</div>

除了视图模型很大时,一切正常。

例如,如果视图模型的大小约为 1 兆字节(包含 80 个文档,每个文档有 60 个值),那么在我的机器上渲染需要两分钟以上。

我想知道是否有办法显着提高性能...或者放弃 Knockout 并在服务器端构建 html 并将其推送到浏览器会更快...

渲染“仅”300kb 的视图模型需要将近 30 秒。

“文档”是由用户定义的,所以甚至有 >2 兆字节的场景(我不知道他们为什么这样做)。

有人在 JavaScript 中使用过大视图模型吗?

【问题讨论】:

    标签: javascript performance knockout.js


    【解决方案1】:

    鉴于您目前无法延迟加载(按需加载)数据的要求,您的能力非常有限。

    服务器端 HTML

    在服务器端生成 HTML 将是最快的方法。但即便如此,如果模型很大,也会有延迟。考虑下载一个 5MB 的 HTML 文件,你的浏览器会花一些时间来解析和渲染这么大的东西。

    仍然使用 KNOCKOUT JS

    如果您还想继续使用您的 Knockout JS 框架,那么我最好的建议是将每个文档放在一个 IFRAME 中。不建议这样做,并且会给您的服务器带来额外的负载,但如果实施得当,将会加快您的用户体验。

    www.mysite.com/view/1
    
    <div>
        <iframe src="www.mysite.com/view/1/document/1"></iframe></div>
    <div>
        <iframe src="www.mysite.com/view/1/document/2"></iframe></div>
    ...
    
    www.mysite.com/view/1/document/1
    
    <!-- Just the single Document template -->
       <table data-bind="foreach: Values">
            <tr data-bind="foreach: $data">
                 <td data-bind="attr: {colspan: Colspan}">
                    <label data-bind="text: Label"></label>
                    <br />
                    <span data-bind="html: Value"></span>
                </td>
            </tr>
        </table>
    

    客户端浏览器最初将获取包含所有 IFRAME 的所有 HTML,它将为每个 IFRAME 异步分派请求。每个单独的 Document 请求都将使用 Knockout JS 在其自己的框架中异步呈现。

    为了改善用户交互,您甚至可以在 IFRAME 上设置加载事件。加载事件可以重新调整 IFRAME 的大小以使没有滚动条,或者从 IFRAME 中提取 HTML 并将 IFRAME 元素替换为提取的 HTML。

    【讨论】:

    • 谢谢。因此,根据您的回答,玩弄我的视图模型的结构并没有真正的帮助?我的意思是,如果我进行两阶段绑定:首先绑定一个空表,然后绑定该表以填充数据等?
    • 另外根据您的经验,尝试其他 MVVM 框架或模板引擎(如主干、jQuery.tmpl 等)是否有意义,或者性能几乎相同?换句话说,它是一般的 JavaScript/浏览器/Dom 问题还是只是 Knockout 很慢?当然,我自己会尝试至少一个其他框架,但是尝试所有这些都需要很多时间,所以这就是为什么我向有经验的人寻求建议:)
    • @Alexey Raga - 任何时候您在客户端进行绑定,您的性能都会受到浏览器的限制。如果有人在使用 IE8(慢 JavaScript 引擎)并且模型很大,他们会花费几分钟来渲染它。如果 jQuery.tmpl 快 50% 对你来说足够了吗?...
    【解决方案2】:

    KO 中的原生模板引擎并不是特别快。我会先尝试 jQuery.tmpl 引擎 (described here)。如果这还不够快,您应该考虑尝试减少正在呈现的内容量 - 例如,最初只为每个文档呈现一个标题,然后在选择或展开它时呈现详细信息。

    【讨论】:

    • 感谢您的回答。我正在与企业讨论这个问题,但就目前而言,他们希望立即渲染所有内容......
    【解决方案3】:

    不确定您的应用程序是如何工作的,但如果您不需要一次显示所有内容,您可以分段填充模型。就像在我的一个应用程序中一样,我有一个视图模型,它有很大的项目列表,但它只包含表格中可见的东西。 View 还选择了包含更多信息的项目条目,当从列表中选择某些条目时,我会填充它。

    一般来说,我很少看到人们将各种东西放在视图模型中,即使它从未在 UI 中呈现。如果你直接从服务器获取你的东西,它有一些好处,但另一方面它可能会使视图模型膨胀。

    【讨论】:

      猜你喜欢
      • 2013-02-04
      • 2013-02-14
      • 2016-05-04
      • 2014-07-05
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      相关资源
      最近更新 更多