我们正在构建一个Angular应用,我们正试图弄清楚如何获得渲染各种页面需要多长时间的基准。我已经阅读了performance.timing
here,但这似乎只适用于非单页应用,因为当我在应用中导航到新视图时,时序数字不会改变。< / p>
理想情况下,我们可以插入一些代码来获取各种视图的渲染时间,并将其发布到我们的Big Query服务中。
有关如何在Angular应用中获取视图的时序信息的任何想法吗?
编辑:
更具体地说,您将转到加载大型重复列表的路径(这对于性能而言不是最佳),并且窗口在实际呈现列表中的项之前有很长的延迟。我们希望了解从大空白视图到呈现列表中的项目所需的时间。
答案 0 :(得分:8)
在做了一些实验之后,我找到了一种方法来估算视图渲染的时间长度。
情景:
ng-repeat
ul
在Angular应用中,ng-repeat
是一个臭名昭着的性能杀手,但它非常方便。 Here's a discussion on the performance和here.
让我们说我们希望得到从#3到#4所需时间的近似值,因为测试AJAX调用性能非常简单。
这里有一些背景信息:
<ul>
<li ng-repeat="item in items">
{{item.name}}
<!-- More content here -->
</li>
</ul>
在Angular控制器内部:
// Get items to populate ng-repeater
MyApiService.getItems(query)
.then( function (data) {
$scope.items = data;
// When callback finishes, Angular will process items
// and prepare to load into DOM
}, function (reason) {
console.log(reason);
});
@runTarm,$routeChangeStart
,$routeChangeSuccess
和$viewContentLoaded
提到的事件会在路由加载后立即触发,但在DOM呈现项目之前,所以他们不会#39解决问题。但是,通过实验,我发现一旦AJAX回调完成并设置$scope.items
,Angular就会开始处理items
并准备插入ng-repeat
ul
的阻止操作DOM。因此,如果您在AJAX调用完成后得到时间,并在回调中指定的setTimeout
中再次获得时间,则setTimeout
回调将排队等待Angular完成转发器进程并在DOM渲染之前的瞬间获得时间,为您提供最接近渲染时间的近似值。它不是真正的渲染时间,但对我们来说,缓慢的部分不是DOM正在做它的工作,而是Angular,这是我们正在寻找的。 p>
以下是经修订的示例:
// Get items to populate ng-repeater
MyApiService.getItems(query)
.then( function (data) {
var start = new Date();
$scope.items = data;
// When callback finishes, Angular will process items
// and prepare to load into DOM
setTimeout( function () {
// Logs when Angular is done processing repeater
console.log('Process time: ' + (new Date() - start));
}); // Leave timeout empty to fire on next tick
}, function (reason) {
console.log(reason);
});
答案 1 :(得分:2)
TypeScript / Angular(2+)回答:
要对角度渲染组件树所花费的时间进行基准测试,请在更改检测之前和之后进行测量。这将计算Angular创建所有子组件并评估ngIf
s / ngFor
等所花费的时间。
有时,当变化检测运行时,什么都不会改变,定时间隔会很小。只需寻找最长的时间间隔,这可能是所有工作发生的地方。此外,最好使用OnPush更改检测策略。见http://blog.angular-university.io/onpush-change-detection-how-it-works/
将此计时器实用程序声明在@Component({...}) class
:
class Timer {
readonly start = performance.now();
constructor(private readonly name: string) {}
stop() {
const time = performance.now() - this.start;
console.log('Timer:', this.name, 'finished in', Math.round(time), 'ms');
}
}
在组件类中添加:
private t: Timer;
// When change detection begins
ngDoCheck() {
this.t = new Timer('component 1 render');
}
// When change detection has finished:
// child components created, all *ngIfs evaluated
ngAfterViewChecked() {
this.t.stop(); // Prints the time elapsed to the JS console.
}
请注意,角度渲染与屏幕上的浏览器渲染(绘画)分开。这也需要时间。当您在Chrome时间线工具(javascript开发者控制台 - &gt;效果 - &gt;记录)中看到javascript(黄色),其中包含大量“checkAndUpdateView”和“callViewAction”调用,这是Angular渲染的发生。当你在Chrome时间线工具中看到紫色标记为“渲染”时,这就是实际的浏览器渲染。
答案 2 :(得分:0)
尝试使用开源Chrome插件Angular-performance,您可以监控Angular应用程序中的摘要时间:https://github.com/Linkurious/angular-performance