【问题标题】:JsRender/JsViews performance issue in Edge and IEEdge 和 IE 中的 JsRender/JsViews 性能问题
【发布时间】:2018-06-15 15:28:16
【问题描述】:

const N_COLS = 20; // use it to modify the number of columns
const N_ROWS = 20; // use it to modify the number of rows

const data = {
  name: "Sample",
  columns: generateColumns(N_COLS),
  rows: generateRows(N_ROWS),
}

function generateColumns(n){
  let columns = [];
  for(let i = 0; i < n; i ++){
    columns.push({ index: i, name : "Column " + i})
  }
  return columns;
}

function generateRows(n){
  let rows = [];
  for(let i = 0; i < n; i ++){
    rows.push({ index: i, fields: generateFields(N_COLS)});
  }
  return rows;
}

function generateFields(n){
    let fields = [];
    for(let i = 0; i < n; i ++){
        fields.push({index: i, text: "Field " + i});
    }
    return fields;
}

$(document).ready(function(){
    console.time('Compile');
    var tmpl = $.templates("#mainTemplate");
    console.timeEnd('Compile');

    console.time('Render');
    tmpl.link("#container", data);
    console.timeEnd('Render');
});
<!DOCTYPE html>
<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>
    </head>
    <body>
        <script id="mainTemplate" type="text/x-jsrender">
            <h1>{{:name}}</h1>
            {{include tmpl="#contentTemplate"/}}
        </script>

        <script id="contentTemplate" type="text/x-jsrender">
            <table>
                <thead>
                    {{for columns}}
                        {{include tmpl="#columnTemplate"/}}
                    {{/for}}
                </thead>

                <tbody>
                    {{for rows}}
                        {{include tmpl="#rowTemplate"/}}
                    {{/for}}
                </tbody>
            </table>
                
        </script>
        
        <!-- In this example, using those templates with an include tag doesn't make sense, but that's because it's a simplified version of what I'm working with -->
        <!-- In my scenario having those templates separated is a must have :( -->
        <script id="columnTemplate" type="text/x-jsrender">
            <th>{{:name}}</th>
        </script>
        
        <script id="rowTemplate" type="text/x-jsrender">
            <tr>
                {{for fields}}
                    {{include tmpl="#fieldTemplate"/}}
                {{/for}}
            </tr>
        </script>

        <script id="fieldTemplate" type="text/x-jsrender">
            <td>
                {{:text}}
            </td>
        </script>

        <div id="container"></div>
    </body>
</html>

我在 Edge 和 IE 中遇到了 JsViews 的性能问题。我有一个非常大的模板,里面有很多包含标签和很多数据链接。在 Chrome 和 Firefox 中,性能还可以,渲染时间不到 1 秒,这对我的需求很有帮助,但在 Edge 和 IE 中,几乎需要 5 秒:(

此模板可以在给定页面中使用任意多次,因此性能问题在此处逐渐增加。

我尝试使用 JsRender 而不是 JsViews,调整我的模板和对象而不使用数据链接,因为我注意到,在我的场景中,使用它们会极大地影响性能,在 Chrome 和 Firefox 中,我实现了 500 毫秒的渲染和在 IE 和 Edge 中.. 2 秒,这仍然满足我的需求。

我已经尝试简化我正在使用的模板,但我已经达到了底线..

我有很多想法可以尝试解决这个问题,这就是我的问题的来源:

  • 是否有(或者会在新的 JsViews/JsRender 版本中)在 Web Worker 中编译模板的方法?我知道在网络工作者中我们不能使用 JQuery、访问 DOM 也不能使用具有自定义原型的对象,但谁知道.. 即使编译时间相同,至少我可以编译 并行模板。

  • 有没有一些神奇的技巧可以提高 IE 和 Edge 中的 JsViews/JsRender 性能? (扔掉 IE 和 Edge 会很好,但不幸的是这不是一个选择:(xD)

PS:恐怕我不能发布任何类型的代码,因为我正在谈论我正在工作的企业的项目。

【问题讨论】:

  • 您是否对缓慢发生的位置进行了分析?模板编译应该只发生在初始页面加载时,所以如果你在每次调用时触发模板或子模板的新编译,那是一个错误。任何模板都应该只编译一次。分析是否表明问题包括重新编译?如果没有,预编译将无济于事....
  • @BorisMoore 模板肯定会编译一次。我注意到我在网络工作者的问题中犯了一个错误,我想说“在网络工作者上渲染”而不是编译^^'
  • JsRender 不需要 jQuery(参见 jsviews.com/#jsr-quickstart)。它也不需要 DOM 来呈现。 (它呈现为 HTML 标记字符串)。但是 JsViews(和数据链接)确实需要 jQuery 和 DOM。要了解您的性能问题,您可能需要展示编码风格的示例,或者创建一个示例/jsfiddle 来说明性能问题,即使您没有显示项目中的特定代码。
  • @BorisMoore 我在 Web Worker 中使用 JsRender 时遇到了一个额外的问题,我使用自定义原型,但我想不出办法将我的对象发送给它。我知道这不是 JsRender 问题,所以顺其自然吧,我会找到解决该问题的方法:p。但是,我会尽快用 jsfiddle 更新我的问题,为您提供我的方案的方法,可能是我的模板或对象可以重新定义以提高性能,感谢您的时间:)
  • @BorisMoore 我用一个简单的 jsfiddle 更新了我的问题,试图展示我正在使用的内容。如果你在 chrome 上运行它,你会注意到编译和渲染平均需要 50 毫秒,但在 edge 中几乎需要 200 毫秒(至少在我的计算机中)。在我的真实场景中,这种差异更大,因为模板和对象更复杂。

标签: javascript web-worker jsrender jsviews


【解决方案1】:

IE 和 Edge 的速度比 Chrome 慢很多——不过具体速度取决于代码和场景的细节。例如,在某些 HTML 表格渲染场景中,IE 比 Chrome 慢得多。您可能会发现,避免使用表格布局,而是使用 CSS 进行等效的网格布局,您会获得很大的性能改进 - 并且在 IE 和 Edge 中可能会更加明显......

如果您在不同的浏览器中查看此http://borismoore.github.io/jsrender/test/perf-compare.html,您会发现 IE 会慢很多,不仅对于 JsRender,对于其他组件或模板引擎也是如此。

除了避免使用 HTML 表格(如果可能的话),您还可以考虑替换:

{{for columns}}
  {{include tmpl="#columnTemplate"/}}
{{/for}}

通过

{{for columns tmpl="#columnTemplate"/}}

如果你可以的话。

另外,小的改进可能来自:

{{... tmpl=~columnTemplate/}}

并提供已编译的模板作为助手,如

var tmpls = {
    columnTemplate: $.templates("#columnTemplate"),
    ...
};

tmpl.link("#container", data, tmpls);

另外,如果您根本没有使用 JsViews 数据链接(我注意到您的所有标签都是 {{...}},而不是 {^{...}}),那么您可以执行 tmpl.render(...) 然后插入 HTML一口气在 DOM 中...

【讨论】:

  • 感谢您的建议,我想我可以尝试的唯一方法是,正如您所说,摆脱表格并使用自定义 CSS 解决方案,因为在我的真实场景中,我已经提供了已编译的模板作为助手并将一行用于/包含。我也避免使用数据链接,因为在 Edge 中,性能指的是非常痛苦的(没有注意到我在我的 jsfiddle 示例中使用了 tmpl.link,对此感到抱歉 ^^')。无论如何,谢谢你的时间:)
猜你喜欢
  • 2012-04-15
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多