我正在开发Angular应用,并尝试分析该应用的性能。为此,我使用了Elasticsearch的Kibana和APM服务器。通过主要获取各种HTTP请求的时间,APM服务器已经能够测量初始页面加载和路由更改的时间。到目前为止,一切都很好。
但是现在我想微调此度量,因为并非每个HTTP请求都在路由更改期间发生。情况是,一个站点上有多个组件,其中许多组件包括PrimeNG表(<p-table>
),这些表无需进行路由更改即可更新,例如当用户在搜索输入中输入内容时。
因此,这是我通过创建装饰器@TimeTracking()
来度量每个组件的寿命的方法,该装饰器扩展了Angular生命周期挂钩ngOnInit()
和ngOnDestroy()
。为了获得有关组件寿命的更多信息,我还测量了ngDoCheck()
和ngOnViewChecked()
之间的性能。
export function TimeTracking(): ClassDecorator {
return function(target: any) {
const lifecycleHooks = ['ngOnInit', 'ngDoCheck', 'ngAfterViewChecked', 'ngOnDestroy'];
lifecycleHooks.forEach(hook => {
const original = target.prototype[hook];
target.prototype[hook] = function ( ...args: any ) {
if (hook === 'ngOnInit') {
// start performance measurement of component
}
else if (hook === 'ngDoCheck') {
// start measurement of checking cycle
}
else if (hook === 'ngAfterViewChecked') {
// end measurement of checking cycle
}
else if (hook === 'ngOnDestroy') {
// end performance measurement for component
}
original && original.apply(this, args);
};
});
};
}
我从How to test rendering speed in Angular和https://netbasal.com/inspiration-for-custom-decorators-in-angular-95aeb87f072c那里得到了这种方法的想法。
此外,我还使用HTTP拦截器来测量每个HTTP请求的时间:
@Injectable()
export class LoggingInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const t0 = performance.now();
let okString: string;
return next.handle(req)
.pipe(
tap(
(event: HttpEvent<any>) => okString = event instanceof HttpResponse ? 'succeeded' : '',
(error: HttpErrorResponse) => okString = 'failed'
),
finalize(() => {
console.log(`${req.method} "${req.urlWithParams}" ${okString} in ${performance.now() - t0} ms.`);
})
);
}
}
简而言之,这是我的问题:
您如何看待这种方法?您还有进一步的想法或改进建议吗?
是否有可能获取有关哪个事件触发了ngDoCheck()
的信息的更多信息?
是否可以将测量到的HTTP请求(在拦截器中)与触发它的组件相匹配?