【问题标题】:DOM recreation performance problems with nested ng-repeat嵌套 ng-repeat 的 DOM 娱乐性能问题
【发布时间】:2015-07-10 03:40:37
【问题描述】:

我正在使用 AngularJS 渲染日历 UI,并且在周转数周时遇到了一些相当大的性能问题。让我解释一下。

用户界面看起来像这样:

我循环遍历所有的人,然后为每个人循环遍历这些天,然后为该用户呈现当天的日历对象。像这样(简化):

<div ng-repeat="user in ::ctrl.users track by user.id" class="row">
    <div ng-repeat="day in ctrl.days" class="cell">
        <div ng-repeat="item in ctrl.items[user.id][day] track by item.id">
            <div class="item">

此页面上的观察者数量并不多(大约 500 个),几乎所有内容都绑定一次。

问题是当用户单击上一个/下一个按钮来加载上一周或下一周时。这会用新的日期更改 ctrl.days 数组,并加载所有正确的项目。在您拥有大量人员和日历项目之前,这可以正常运行。那么所有 DOM 元素的销毁和重新创建真的很慢。

我遇到了 sly-repeat 指令,该指令旨在缓存和重用 DOM 元素,但由于我的外部 ng-repeat 更改(ctrl.days),内部 ng-repeat(带有项目)也被重新创建。所以它并没有真正起作用。

我该如何解决这个问题?现在浏览大型数据集需要大约 2 秒的时间,这当然是不可接受的。只需一小部分用户和日历项目,一切都非常活泼。

【问题讨论】:

  • 为所有天(即所有周)生成 DOM,并让前一周和下周按钮更改索引。然后,您可以使用此索引来更改日期的可见性(或其他一些 CSS 类)。希望这是有道理的。
  • 日历基本上是无限的,并不是预先生成所有这些项目的选项。即使我将它限制为 4 周,它仍然是成千上万的 DOM 元素......
  • 如果您的视口大小将被固定。您可以预先创建 DOM 并单独换出值。
    {{x}}
    {{y}}
    {{z}}
    之类的东西,您只需更改 x、y、z 而不是循环通过具有 x、y 和 z 的集合并创建 div。如果我理解正确,您的开销是由于 DOM 创建/重新创建 - 所以这应该会有所帮助(但会增加复杂性)
  • 在尝试/发明了很多相同问题的解决方案之后......,我的结论是在指令中使用 react.js。当数据更新必须手动时,**controller => directive **。类似$scope.watch('data' ,function(newval) { myReactDirective.update(newval) }); 这是一个防弹解决方案
  • 您也可以摆脱其中一个 ng-repeats,因为页面上的天数可能不会改变。

标签: angularjs performance dom angularjs-ng-repeat


【解决方案1】:

尝试在嵌套的 ng-repeats 中使用 track by。这将防止他们重新加载不必要的内部重复。有关详细信息,请参阅:

http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

【讨论】:

  • 这无济于事,因为所有项目都是独一无二的。当外部重复发生变化时,内部重复也会发生变化。
  • 我们最终使用了github.com/kamilkp/angular-vs-repeat,它非常适合我们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
相关资源
最近更新 更多