我如何衡量AngularJS应用程序摘要循环的性能?

什么是测量angularjs摘要周期持续时间的简单方法? 有各种方法来分析摘要循环的性能,但是每个都有自己的坑:

  • Chrome Profiler:太多的细节,并没有以简单易懂的方式打破文摘循环
  • Batarang(AngularJS浏览器插件):开销太大,刷新速度慢,大应用程序爆炸。

…一定有更好的办法?!1?

这是一个秘密。 在chrome开发工具中,运行一个cpuconfiguration文件。 停止捕捉之后,屏幕底部将出现“Heavy(Bottom Up)”旁边的向下三angular形。 点击三angular形并select“火焰图”。 一旦进入火焰图表模式,您可以缩放和平移以查看摘要循环,它们需要多长时间,以及确切地调用了哪些函数。 火焰图对追踪页面加载问题非常有用,ng-repeat性能问题,消化周期问题! 我真的不知道我是如何在火焰图表之前进行debugging和configuration的。 这里是一个例子:

Chrome开发工具中的火焰图表

下面的答案会告诉你$ digest循环的空闲性能,也就是当你的expression式没有任何变化时摘要的性能。 如果您的应用程序即使在视图没有改变的时候看起来很慢,这也是有帮助的。 对于更复杂的情况,请参阅aet的答案。


在控制台中键入以下内容:

angular.element(document).injector().invoke(function($rootScope) { var a = performance.now(); $rootScope.$apply(); console.log(performance.now()-a); }) 

结果会给你消化周期的持续时间,以毫秒为单位。 数字越小越好。


注意:

Domi在评论中指出:如果您使用ng-app指令进行初始化, angular.element(document)将不会产生太多的效果。 在这种情况下,请改为使用ng-app元素。 例如通过做angular.element('#ng-app')

你也可以尝试:

 angular.element(document.querySelector('[ng-app]')).injector().invoke(function($rootScope) { var a = performance.now(); $rootScope.$apply(); console.log(performance.now()-a); }) 

这里有一个新的工具,我发现它有助于分析剖析: Digest-HUD

在这里输入图像说明

你也可以使用angular度性能

该扩展提供了观察者数量,摘要时间和摘要率的实时监控图表。 您还可以获得摘要计时分配,以便您可以从更多的recursion模式中获得特别长的摘要计时,并将所有实时数据链接到事件,以便确定哪些操作会改变应用程序性能。 最后,你可以定时服务方法并计算它们的执行时间,以确定那些对你的应用运行时间影响更大的方法。

Angular性能截图

Disclamer:我是这个扩展的作者

可以通过@kentcdodds的优秀的ng-stats工具find一个方便的工具来关注摘要循环。 它创build了一个像这样的小视觉元素,甚至可以通过小书签来实现。 它甚至可以用在像jsfiddle这样的iFrame内部。

好消化周期 在这里输入图像说明

小实用程序显示您的网页的angular度摘要/手表的统计资料。 这个库目前有一个简单的脚本来生成一个图表(见下文)。 它还创build了一个名为angularStats的模块,该模块具有一个叫做angular-stats的指令,可以将angular度统计信息放在指定页面上的特定位置。

https://github.com/kentcdodds/ng-statsfind

您可以使用UX Profiler

  • 用户交易视图,即CLICK和由它引起的所有活动(其他事件,XHR,超时)组合在一起。
  • 时间测量(如用户所感觉到的)整个用户交易和/或其部分。
  • 组合asynchronous堆栈跟踪。
  • 专注的分析器 – 简介只是有问题的事件。
  • Angular 1.x集成。

在这里输入图像说明

上面描述的工具已经给了你衡量消化循环性能的想法大多数重要的提高消化循环性能的要素是

  • 监视紧密滚动的事件隐藏所有不可见的元素和
    大大减less了观察者的数量。

  • 所有其他事件都有可pipe理的消化周期。

对于严格的模式,一个运行的消化cucle,运行在f12控制台在铬

 angular.element(document).injector().invoke(['$rootScope',function($rootScope) { var a = performance.now(); $rootScope.$apply(); return performance.now()-a; }])