【问题标题】:How can I optimize Mustache rendering speed when rendering 8000+ items?渲染 8000 多个项目时如何优化 Mustache 渲染速度?
【发布时间】:2013-01-16 15:34:30
【问题描述】:

我正在尝试渲染一个表格,因此模板非常简单;行模板如下所示:

  <script type=\"text/mustache\" id=\"template-list-records\">
  {{#.}}
   <tr>
    <td>{{airport_code}}</td>
    <td>{{city_code}}</td>
    <td class=\"pull-right\">
     [<a href=\"result.mics?m_uid={{airport_code}}\" class=\"listlink\">details</a>]
    </td>
   </tr>
  {{/.}}
  </script>

问题在于,当渲染超过 1000 个结果时,渲染速度开始呈指数下降(我猜它一直呈指数下降 :),但在 1000 多个结果时,渲染速度显然不是线性的)。现在,在 4000 个结果中,页面加载时间为 2.3 秒。在 7000 个结果时,渲染时间为 7.3 秒,渲染完整结果集(大约 8500 个结果)需要 10 秒。现在,我不需要将其加速到超过 8 秒来完全加载结果(因为这是旧功能渲染页面所花费的时间),这将是一个奖励 :),但我仍然需要剃须 2 秒。我查看了 Timeline 检查器,时间都花在了渲染上;渲染在 2.5 秒后开始。

我猜部分问题可能出在我的笔记本电脑上(我有一些显卡问题),但我仍然感兴趣是否有办法加快速度,例如预编译包含 8500 行的表,并在需要时添加/删除行(这确实是一个机场列表,所以数字不会经常变化,而且当它发生变化时,变化也不大)。

【问题讨论】:

    标签: performance optimization rendering mustache


    【解决方案1】:

    新想法:为什么不增量渲染页面呢?我想 8500 行是相当多的“页面”(在 1080p 屏幕上肯定有大约 200 个“页面”),因此您可以轻松实现连续滚动机制,根据需要将数据保持在小块中。

    假设您开始渲染前 500 个项目(这已经很多),然后当用户开始滚动并接近总滚动大小的 80% 左右时,您会渲染 200 额外的行。你一直这样做,直到你用完要渲染的行。

    如果您有一个要求,即您需要立即获得所有可用的东西(例如,以便用户可以 ctrl+F),您仍然可以尝试以块的形式呈现:而不是为您的模板提供整个数据集,将其分解为 500 个一组,并使用这些较小的组根据需要多次调用 Mustache。如果它仍然阻塞,请在调用之间添加一个小超时以提高感知响应能力。

    TBH,我重新阅读了您的问题,您的大部分时间似乎都花在了试图计算您的表格布局的浏览器上,因此这些建议应该适用于您的情况。作为最后的手段,您可以尝试使用 CSS table-layout: fixed;,这将大大加快您的表格呈现速度,但也会迫使您手动定义列宽,因为表格将不再根据其内容动态调整列宽。

    【讨论】:

    • 我有 CTRL+F 要求,否则我会实现我们经典的 50+ 项分页。我会尝试将渲染分解成块,看看会发生什么。
    • 我尝试过实现这一点,并在此过程中意识到问题不在于 Mustache/Hogan,问题似乎在于 Backbone.js。我在 Backbone.View 中进行渲染,我扩展了渲染方法,该方法需要时间来退出/渲染,所以我必须看看 Backbone.js 优化
    • 最后,我决定只得到 10 个结果并进行分页。但我也发现了问题——我的解析器实现。正确的实现是解析所有结果并将它们连接到内存中,然后才输出结果。我的实现渲染并附加了每个元素(更新了 DOM),这触发了重绘.. 大约 8000 次:D 现在很有趣,但不是在我问的时候 :)
    【解决方案2】:

    您是否尝试过其他 Mustache 实现,例如 HoganHandlebars

    您的模板很小,因此使用预编译模板功能不会给您带来太多好处,但特别是在 Hogan 的情况下,它经过微调以尽可能加快渲染算法,所以有机会只需使用替代实现而不是 vanilla Mustache 就可以解决您的问题。

    另外,如果您还没有使用最新版本的 Mustache.js,您可以尝试简单地升级。旧版本(大约 1.5 年)存在严重的性能问题。

    【讨论】:

    • Mustache 版本没什么区别,我试过用最新版本渲染,速度一样。我读到了关于 Hogan/Handlebars 的文章,但希望只用 Mustache 就能做点什么。
    • Hogan is“只是 Mustache”,它的语法和解释都与 Mustache spec 保持一致,因此与 Handlebars 不同的是,不会有疏远模板的诱惑。您甚至可以在 Hogan 之上编写一个包装器,以避免更新所有代码以使用新 API,至少出于测试目的。
    • 我将尝试 Hogan 并针对 Hogan.js 的问题提出一个新问题 :)
    • 我已经设法用 Hogan 解析,但我仍然得到相同的速度 :(
    • 现在我们确定问题出在数据量而不是算法上,因此要添加另一个答案。
    【解决方案3】:

    如何将胡须渲染的 HTML 添加到 DOM 中?

    尝试一次性添加渲染代码,而不是连续插入。

    慢,插入很多:

    for () {
      table.innerHTML = table.innerHTML + Mustache.render(row);
    }
    

    更快,1 次插入:

    var buffer = '';
    for () {
      buffer = buffer + Mustache.render(row);
    }
    table.innerHTML = buffer;
    

    【讨论】:

    • 问题已通过类型化功能解决,但我认为真正的问题是,正如您所提到的,DOM 插入/重新渲染。
    猜你喜欢
    • 1970-01-01
    • 2012-02-07
    • 2018-09-10
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 2015-09-28
    • 1970-01-01
    相关资源
    最近更新 更多