How to monitor the slowness of your Angular web app's HTTP requests and API calls

Daniel Kreider
Daniel Kreider
Published on 13. Apr. 2021
  • HTTP Logging
  • Angular Interceptor
  • Angular Performance

The simple-pimple guide to expose slow HTTP requests that are frustrating users and no doubt causing revenue loss.

Without installing moment.js and bloating your Angular app

Some web apps act like a dying cow.

And would you believe it?

These web apps are bogged down with silly-jiggy-jaggy-dancing spinners...

...that seem to think they'll hypnotize us into patiently waiting those extra 8.3 seconds!

It's like waiting on a turtle for a horse ride.

Say, can't we do better?

How can we find the HTTP requests in our Angular application that are too slow? Once we've uncovered the bottle-necks we can fix them and make your HTTP requests zippy fast.

We could then connect our Angular app to a monitoring service like Application Insights and get alerts for turtle-performance.

Why just imagine it! About the time your boss shows up saying that users are complaining of slowness you'd tell him "I just got done fixing it!" and he'd be so surprised he'd swallow his gum.

Nope, I'm not selling you snake oil. Read on to learn this stuff for yourself my friend.

Create an Angular HTTP Interceptor

We'll begin by adding a good ole HTTP Intercepter to our Angular project.

Open a terminal in your Angular project and whip it up with the Angular CLI like so.

ng generate interceptor monitor

And then we'll import it into our module file by adding it to the providers array.

providers: [
    { 
      provide: HTTP_INTERCEPTORS, 
      useClass: LoadingInterceptor, 
      multi: true
    }
]

Harness the interceptor

Next we'll open the new monitor.interceptor.ts file. It should look something like this.

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class MonitorInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request);
  }
}

And we'll want to modify it to look like this.

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { LoadingService } from '../services/loading.service';

@Injectable()
export class MonitorInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const begin = performance.now();
    return next.handle(request).pipe(
      finalize(() => {
        this.logRequestTime(begin, request.url, request.method);
      })
    );
  }

  private logRequestTime(startTime: number, url: string, method: string) {
    const requestDuration = `${performance.now() - startTime}`;
    console.log(`HTTP ${method} ${url} - ${requestDuration} milliseconds`);
  }
}

Parting thoughts...

And that's it! We've built an HTTP interceptor that will monitor every outgoing HTTP request and tell us how long it took.

Over to you buster. Now you can take that logRequestTime function and jazz it up with whatever kind of functionality you want.

Simple pimple? Well... I told you so.

Questions or comments? Please don't hesitate to contact me.

Angular & .NET Core Expert