我正在开发一个 Angular 应用程序并尝试分析这个应用程序的性能。为此,我使用 Elasticsearch 的 Kibana 和 APM 服务器。APM 服务器已经能够通过主要获取各种 HTTP 请求的时间来测量初始页面加载和路由更改的时间。到目前为止,一切都很好。
但现在我想微调这个测量,因为不是每个 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 请求(在拦截器中)与触发它的组件相匹配?