AngularJS异常高的内存消耗

Posted

技术标签:

【中文标题】AngularJS异常高的内存消耗【英文标题】:AngularJS unusually high memory consumption 【发布时间】:2017-10-30 23:00:38 【问题描述】:

我有一个渲染大约 200-250 个元素的 AngularJS 应用程序。每个重复元素都包含内部项目,其中一些具有嵌套的 ng-repeats。运行时,JS Heap 内存分配在 70MB 左右,导致网页多次崩溃,如果没有,肯定会影响其他打开的选项卡。 Batarang 建议大约有 3000 多个 Scope 项目(带有 $id )。我在一定程度上重组了我的指令,只有大约 700-800 个 Scope 项目。但是内存消耗超出了图表,并且性能没有明显改善。 然而,在运行分析工具时,如果我点击垃圾收集器图标,内存消耗确实下降了大约 15 MB。 谁能告诉我我应该如何调试这样的问题?

更新: 以下是被重复的指令结构:

<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>

【问题讨论】:

您是否根据事件侦听器检查是否存在内存泄漏?如果您附加侦听器,则需要在实例被销毁时分离它们(又名$destroy)。另外,请尝试检查您是否可以在某处使用one-time binding...您是否跟踪了您的ng-repeat 是的。跟踪 ng-repeat。另外,我想,我不明白什么时候调用 $destroy 。除了 ng-repeat 之外,我没有从页面中动态添加或删除的额外元素。另外,我如何检查悬空的听众? 它通常发生在您手动注册侦听器时(angular.element(...).on(String, Function),因此,Angular 不知道如何在 $destroy 元素实例时分离它们。 但是我没有从 DOM 中删除任何元素。在某些情况下,可能会有一个空对象上的 ng-repeat,在这种情况下,我会附加一个带有自定义消息的空 div ng-repeat 在每次模型更改时重绘...此外,view filters 的使用会影响性能...您应该尝试直接从控制器提供格式良好的数组。 【参考方案1】:

ng-repeat 附加观察者。您需要将所有这些优化为“单向绑定”

像这样:

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

还要注意模板中的此类结构,例如smth。请改用::smth

另外,不要使用$watch$broadcast$emit。始终使用 '&lt;' 而不是 '=' 作为绑定。 如果你使用 angular 1.5+,你可以使用生命圈钩子。

$onDestroy() 
  // your code

【讨论】:

【参考方案2】:

这是实现它的方法:

//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();
 );

【讨论】:

以上是关于AngularJS异常高的内存消耗的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AngularJS 中捕获/处理后端异常

如何使用 Chrome DevTools 在 AngularJS 异常中暂停脚本执行?

AngularJs - 服务器抛出异常''XMLHttpRequest 无法加载预检的“URL”响应无效(重定向)'

spring安全管理网关和angularjs异常

angularjs中jsonp请求的异常处理

Promise.catch() 不会在 AngularJS 单元测试中捕获异常