8

我有以下代码

<table>
 <thead><td>Id</td><td>Name</td><td>Ratings</td></thead>
 <tbody>
   <tr ng-repeat="user in users">
    <td>{{user.id}}</td>
    <td>{{user.name}}</td>
    <td><div ng-repeat="item in items">{{item.rating}}</div></td>
   </tr>
 </tbody>
</table>

users 是一个只有 id 和 name 的用户对象数组。数组中的用户对象数 - 150

items 是一个只有 id 和 rating 的 item 对象数组。数组中的项目对象数 - 150

当我在浏览器中渲染它时,当我尝试在我的 chrome - v23.0.1271.95 中进行分析时,它需要大约 250MB 的堆内存。

我正在使用 AngularJS v1.0.3。

角度有问题还是我在这里做错了什么?

这是JS小提琴

http://jsfiddle.net/JSWorld/WqSGR/5/

4

3 回答 3

12

好吧,这不是 ng-repeat 本身。我认为这是您使用 {{item.rating}} 添加绑定的事实。

所有这些绑定都在范围上注册手表,因此:

  • 150 * 2 = 300(对于 2 个用户信息)
  • 150 * 150 = 22500(用于评级信息)
  • 总共 22800 个手表函数 + 22800 个 dom 元素。

这会将内存推到可以想象的 250MB 的值

来自angularjs 中的数据绑定

你不能在一个页面上向人类展示超过2000条信息。除此之外的任何东西都是非常糟糕的用户界面,人类无论如何也无法处理它。

于 2012-12-28T11:19:58.497 回答
0

我想说泄漏在第二个数组中,因为您可能会遍历同一个数组并显示 users 中每个用户行的每个项目,因此取决于您的测试数据有多大,该视图可能会变得相当大。我可以做更多的调查。顺便说一句,你的小提琴完全不同。

于 2012-12-28T06:01:03.640 回答
0

现在,您正在循环 150 X 150 = 22500 个项目。并为每个手表注册一个手表(或通过指令添加项目评级)。

相反 - 考虑将用户的评分添加到用户对象本身。它会增加每个用户对象的大小,但您只会循环 150 个项目并仅在它们上注册手表。

另外 - 考虑查看索引。很明显,可能存在相似的用户或项目评级。只需索引它们,因此您可以减少它们,而不是遍历重物。

还有一件事 - 如果您要在同一个实例中运行指令,至少更改代码:

var text = myTemplate.replace("{{rating}}",myItem.rating);

到 concat 样式字符串计算:

var text = '<div>' + myItem.rating + '</div>';

这将为您节省大量的计算。我已经为这个案例制作了一个JSperf,注意区别,它快了大约 99% ;-)

于 2013-08-20T19:20:36.817 回答