Soham Bhaumik
Soham Bhaumik

Reputation: 241

AngularJS unusually high memory consumption

I have an AngularJS application that renders around 200-250 elements . Each of the repeated elements contains inner items , and some of them have nested ng-repeats. On running, the JS Heap memory allocation was around 70MB which caused the webpage on several occasions to crash and if not, definitely affect other open tabs. Batarang suggested that there were around 3000+ Scope items( with $id ). I restructured my directives to a point, there are only around 700-800 Scope items. But the memory consumption is off the charts and there is no marked improvement in performance. However while running the profiling tool, if i do click on the garbage collector icon, the memory consumption does drop by around 15 MB. Can anybody tell ne as to how I should be going about debugging such a a problem ?

UPDATE: the following is the directive structure being repeated:

<li class="reminder-content">
   <wizards/>
   <editwidget></editwidget>
   <div style="font-size:87%;padding-left:5px;">{{::reminder.time| date:"shortTime"}} <span class="date-particulars">{{::reminder.time | dateFilter}}<span class="date-particulars-date">Reminder was set for <strong>{{::reminder.time | date:"longDate"}}</strong></span></span></div>
   <div class="reminder-body">
      <p class="{{reminder.trip.destination}}">{{::reminder.trip.destination}}</p>
      <p class="pad-top">{{::reminder.text}}</p>
      <p class="pad-top"  id="trav_name"><a href="{{::reminder.traveler.conversationLink}}" target="_blank">{{::reminder.traveler.name}}</a></p>
      <p>{{::reminder.wizard.id | customFilter:this}}</p>
   </div>
</li>



<reminder ng-repeat="reminder in reminders.delegatedReminders track by reminder._id| orderBy:'time'"></reminder>

Upvotes: 5

Views: 1390

Answers (2)

John Doe
John Doe

Reputation: 506

ng-repeat attaches watchers. You need to optimize all this to 'one-way binding'

Like so:

ng-repeat="item in ::$ctrl.items"

Also be aware of such constructions inside templates, like {{smth}}. Use {{::smth}} instead.

Also, don't use $watch, $broadcast, $emit. Always use '<' instead of '=' as bindings. If you are using angular 1.5+, you can use life circle hooks.

$onDestroy() {
  // your code
}

Upvotes: 5

Nainish Modi
Nainish Modi

Reputation: 488

This is how you can achieve it:

//catch the results returned by $watch
var deReg = $scope.$watch('yourModelValue', function(){

    //your code
});

//De-register watch on destroy event
$scope.$on('$destroy', deReg);

//or you can do it following way if u have multiple watches

 $scope.$on('$destroy', function() {
   deReg();
 });

Upvotes: 1

Related Questions