Emp*_*nal 9 javascript performance performance-testing angularjs
我们正在构建一个Angular应用程序,我们正试图弄清楚如何获得渲染各种页面需要多长时间的基准.我在performance.timing
这里读过,但这似乎只适用于非单页面应用程序,因为当我在应用程序中导航到新视图时,时序数字不会改变.
理想情况下,我们可以插入一些代码来获取各种视图的渲染时间,并将它们发布到我们的Big Query服务中.
关于如何在Angular应用程序中获取视图的时序信息的任何想法?
编辑:
更具体地说,您将转到加载大型重复列表的路径(这对于性能而言不是最佳的),并且窗口在实际呈现列表中的项之前有很长的延迟.我们想看看从大空白视图到渲染列表中的项目需要多长时间.
Ale*_*lor 12
TypeScript / Angular (2+) 答案:
要对 Angular 渲染组件树所花费的时间进行基准测试,请在更改检测之前和之后进行测量。这将计算 Angular 创建所有子组件并评估ngIf
s / 所需的时间ngFor
s 等所需的时间。
有时,当更改检测运行时,什么都不会改变,时间间隔会很小。只需寻找最长的时间间隔,这可能就是所有工作发生的地方。此外,最好为此使用 OnPush 更改检测策略。见http://blog.angular-university.io/onpush-change-detection-how-it-works/
在你的上面声明这个 Timer 实用程序@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');
}
}
Run Code Online (Sandbox Code Playgroud)
在你的组件类中添加这个:
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.
}
Run Code Online (Sandbox Code Playgroud)
请注意,Angular 渲染与屏幕上的浏览器渲染(绘制)是分开的。这也需要时间。当您在 Chrome 时间线工具(javascript 开发人员控制台 -> 性能 -> 记录)中看到带有大量“checkAndUpdateView”和“callViewAction”调用的 javascript(黄色)时,即发生了 Angular 渲染。当您在 Chrome 时间线工具中看到标有“渲染”的紫色时,这就是实际的浏览器渲染。
在做了一些实验之后,我找到了一种方法来估计视图渲染的时间长度.
场景:
ng-repeat
ul
在Angular应用程序中,ng-repeat
是一个臭名昭着的性能杀手,但它非常方便.下面是关于性能的讨论,并在这里.
假设我们希望得到从#3到#4所需时间的近似值,因为测试AJAX调用性能非常简单.
这是一些背景:
<ul>
<li ng-repeat="item in items">
{{item.name}}
<!-- More content here -->
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
在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);
});
Run Code Online (Sandbox Code Playgroud)
通过@runTarm,提到的事件$routeChangeStart
,$routeChangeSuccess
以及$viewContentLoaded
一旦路径被加载火,但DOM渲染项目之前,所以他们不解决问题.但是,通过实验,我发现一旦AJAX回调完成并设置$scope.items
,Angular就会开始处理items
和准备ng-repeat
ul
插入DOM 的阻塞操作.因此,如果您在AJAX调用完成后得到时间,并setTimeout
在回调中指定的时间内再次获得时间,则setTimeout
回调将排队等待Angular完成转发器进程并让您在时间段前一瞬间获得时间. DOM渲染,为您提供最接近渲染时间的近似值.它不是实际的渲染时间,但对我们来说缓慢的部分不是DOM正在做它的工作,而是Angular,这是我们想要测量的.
这是修改后的例子:
// 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);
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8131 次 |
最近记录: |