AngularJS ng-repeat 性能问题

3
我使用AngularJS的ng-repeat来查看我的表元素(我知道它不应该经常使用,但我不知道其他方法)。以下是我展示containerObjects在表格中的示例: http://jsfiddle.net/NfPcH/10390/
ng-repeat=...

我有很多包含起始、结束和容器类型的containedObjects(每页约600个),它们显示在表格中。显示视图需要大约3秒钟。
我的问题是,是否有可能通过替换/更改ng-repeat来减少加载时间以提高性能?
非常感谢!
[编辑]
我还有这个函数调用,但我不知道如何防止函数调用。有人有任何想法如何改进吗? 非常感谢!
ng-repeat="serviceSchedule in getServiceScheduler(institutionUserConnection)">

function getServiceScheduler(institutionUserConnection) {
        if(institutionUserConnection.scheduler != null) {
            var serviceSchedules = institutionUserConnection.scheduler.serviceSchedules;
            return serviceSchedules[Object.keys(serviceSchedules)[0]];          
        } else {
            return null;
        }
    }

1
getCurrentDateScheduler()中的institutionUserConnection << 对于大数组总是不好的想法。引用变量,而不是方法。 - Petr Averyanov
为什么视图中有这么多函数调用? 这些很耗费资源。 如果需要,请进行一些数据预处理。 - charlietfl
我已经编辑了我的帖子 - 有人有什么想法可以改进吗?非常感谢! - quma
1个回答

11

改进 #1:

如@Petr Averyanov所建议,使用变量而不是函数调用。

将代码从: ng-repeat="serviceSchedule in getServiceScheduler(institutionUserConnection)" 改为: ng-repeat="serviceSchedule in preCalculatedServicesObjectInScope"

为此,您需要在控制器中进行其他逻辑更改,您必须自己管理getServiceScheduler(institutionUserConnection)结果何时实际更改,但这将增加性能。

改进 #2:

如果行的值一旦呈现就不会更改,请使用仅评估一次的变量。这将显着减少监视程序并帮助提高整体性能:

```html
<tr ng-repeat="institutionUserConnection in someScopeVariable">
  <td>{{ ::institutionUserConnection.user.firstname }} {{ ::institutionUserConnection.user.lastname }}</td>
</tr>```

改进 #3:

ng-repeat中使用track by语句。Angular.js通常使用特殊哈希函数$id来检查/尝试识别每个对象在ng-repeat中的身份。然而,由于数组中自然而然地存在一个标识符(且应该存在),因此你可以让ng-repeat使用它而不是创建自己的ID。例如:

<tr ng-repeat="x in someScopeVariable track by x.id">

改进 #4:(变得更加刻意)

无论你做什么,由于你的数组很大,你可能无法提高足够的性能。那么你应该问自己这个问题,人们是否真的能在一眼看到600项?不行,它不能适合页面。因此,你可以截断无法适配页面的部分,每次只渲染需要呈现的DOM元素。为此,你可以使用limitTo过滤器:

<tr ng-repeat="x in someScopeVariable | limitTo: visual.limitValue">

你可以在开始时将visual.limitValue设置为一个合理的计数,例如10,在表格的scroll上增加它以在用户即将到达底部时增加它,从而导致DOM的部分追加到页面。然而,这种hack需要页面中的样式和代码更改。

改进 #5:(最刻意的一种方法,但它有效)

如果每行的维度是恒定的,使用滚动位置和行的尺寸,你可以计算出哪些行应该可见,然后只呈现它们。我写了一个指令来练习,命名为uber-repeat并测试了它与60,000个行,性能非常出色,即使在手机上也是如此!

我认为有一个项目在这里使用了类似的方法:angular-vs-repeat


非常感谢您的回答 - 它非常有帮助!我还有一个问题 - 如果我滚动浏览器视图(我的表格未嵌入),是否有示例可以说明如何使用visual.limitValue?非常感谢! - quma
使用 $index 追踪在我的用例中起了奇效(只有大约 500 个对象,但已经导致不可接受的延迟)。 - David Simic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接