如何提高ngRepeat在巨大数据集(angular.js)上的性能?

我有一个庞大的数据集,有几千行,每行大约有10个字段,大约2MB的数据。我需要在浏览器中显示它。最直接的方法(获取数据,将其放入,让我们完成其工作)工作正常,但是当浏览器开始将节点插入DOM时,它会冻结浏览器大约半分钟。我应该如何处理这个问题?$scopeng-repeat=""

一种选择是以增量方式追加行,并等待完成将一个块插入 DOM,然后再移动到下一个块。但是AFAIK ngRepeat在完成“重复”时不会报告回来,所以它会很丑陋。$scopengRepeat

另一种选择是将服务器上的数据拆分为页面,并在多个请求中获取它们,但这更丑陋。

我浏览了Angular文档,寻找类似的东西,但什么也没找到。我对Angular方式相当陌生,所以有可能我完全错过了重点。这方面的最佳实践是什么?ng-repeat="data in dataset" ng-repeat-steps="500"


答案 1

我同意@AndreM96,最好的方法是只显示有限数量的行,更快更好的UX,这可以通过分页或无限滚动来完成。

无限滚动与Angular是非常简单的极限过滤器。您只需要设置初始限制,当用户要求更多数据时(为了简单起见,我使用按钮),您就会增加限制。

<table>
    <tr ng-repeat="d in data | limitTo:totalDisplayed"><td>{{d}}</td></tr>
</table>
<button class="btn" ng-click="loadMore()">Load more</button>

//the controller
$scope.totalDisplayed = 20;

$scope.loadMore = function () {
  $scope.totalDisplayed += 20;  
};

$scope.data = data;

这是一个JsBin

这种方法对于手机来说可能是一个问题,因为通常在滚动大量数据时它们会滞后,因此在这种情况下,我认为分页更适合。

为此,您将需要 limitTo 筛选器和一个自定义筛选器来定义所显示数据的起点。

这是一个带有分页的JSBin


答案 2

使用大型数据集克服这些挑战的最热门 - 也可以说是最可扩展的 - 方法体现在Ionic的collectionRepeat指令和其他类似实现的方法中。一个花哨的术语是“遮挡剔除”,但你可以把它总结为:不要只是将渲染的DOM元素的数量限制为任意(但仍然很高)的分页数字,如50,100,500...相反,请仅限制为用户可以看到的尽可能多的元素

如果你做一些通常被称为“无限滚动”的事情,你会减少一些初始的DOM计数,但它在几次刷新后会迅速膨胀,因为所有这些新元素都只是贴在底部。滚动是爬行的,因为滚动完全与元素计数有关。没有什么是无限的。

然而,方法是仅使用适合视口的任意数量的元素,然后回收它们。当一个元素旋转出视图时,它将从呈现树中分离出来,重新填充列表中新项的数据,然后重新附加到列表另一端的呈现树。这是人类已知的将新信息传入和传出DOM的最快方法,利用有限的现有元素集,而不是传统的创建/销毁周期。创建/销毁。使用这种方法,您可以真正实现无限滚动。collectionRepeat

请注意,您不必使用Ionic来使用/破解/适应 ,或任何其他类似的工具。这就是为什么他们称之为开源。:-)(也就是说,Ionic团队正在做一些非常巧妙的事情,值得你注意。collectionRepeat


至少有一个很好的例子在 React 中做了一些非常相似的事情。只是您不是使用更新的内容回收元素,而是简单地选择不渲染树中不在视图中的任何内容。它在5000个项目上非常快,尽管它们非常简单的POC实现允许一些闪烁...


也。。。呼应其他一些帖子,使用是非常有帮助的,即使使用较小的数据集。认为这是强制性的。track by