Chubby Boy
Chubby Boy

Reputation: 31062

Angular JS ng-repeat consumes more browser memory

I have the following code

<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 is an array of user objects with only id and name. number of user objects in array - 150

items is an array of item objects with only id and rating. number of item objects in array - 150

When i render this in browser, it takes about 250MB of heap memory when i tried profiling in my chrome - v23.0.1271.95.

I am using AngularJS v1.0.3.

Is there an issue with angular or am i doing anything wrong here?

Here is the JS fiddle

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

Upvotes: 8

Views: 4290

Answers (3)

Gilad Peleg
Gilad Peleg

Reputation: 2010

Right now you are looping through 150 X 150 = 22500 items. And registering a watch (or through a directive just adding item rating) to each one.

Instead - consider adding the user's rating to the user object itself. It will increase the size of each user object but you will only loop through 150 items and register watches only on them.

Also - consider looking into Indexes. It's apparent that there could be similar users or item ratings. Just index them, so instead of looping through heavy objects, you can reduce them.

One more thing - if you are going to be running the directive the same instance, at least change the code:

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

to a concat style string calculation:

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

This will save you a HUGE chunk on calculation. I've made a JSperf for this case, notice the difference, it's about 99% faster ;-)

Upvotes: 0

Liviu T.
Liviu T.

Reputation: 23664

Well it's not the ng-repeat per se. I think it's the fact that you are adding bindings with the {{item.rating}}.

All those bindings register watches on the scope so:

  • 150 * 2 = 300(for the 2 user infos)
  • 150 * 150 = 22500(for the rating info)
  • Total of 22800 watch functions + 22800 dom elements.

That would push the memory to a conceivable value of 250MB

From Databinding in angularjs

You can't really show more than about 2000 pieces of information to a human on a single page. Anything more than that is really bad UI, and humans can't process this anyway.

Upvotes: 12

ChrisMcKenzie
ChrisMcKenzie

Reputation: 387

I want to say the leak is in the second array because you are potentially looping through the same array and displaying every item for every user row in users so depending on how large your test data is that view could get rather large. I could do a little more investigating. btw your fiddle is something entirely different.

Upvotes: 0

Related Questions