How to test rendering speed in Angular

EmptyArsenal picture EmptyArsenal · Aug 14, 2014 · Viewed 11.4k times · Source

We're building an Angular app, and we're trying to figure out how to get some benchmarks on how long it takes to render various pages. I've read about performance.timing here, but that seems to only be useful with non-single page applications as when I navigate to new views in our app, the timing numbers do not change.

Ideally, we'd be able to insert some code that gets render time for various views and posts it our our Big Query service.

Any ideas on how to get some timing information for views in an Angular app?

EDIT:

More specifically, you go to a route which loads a big ng-repeat list (which is not optimal for performance), and the window has a long delay before it actually renders the items in the list. We'd like to see how long it takes to go from the big blank view to rendering the items in the list.

Answer

Alexander Taylor picture Alexander Taylor · Jun 27, 2017

TypeScript / Angular (2+) answer:

To benchmark the time spent in Angular rendering the component tree, measure before and after change detection. This will time how long it takes Angular to create all the child components and evaluate ngIfs / ngFors etc.

Sometimes when change detection runs, nothing will have changed and the timed interval will be small. Just look for the longest time interval and that's probably where all the work is happening. Also, best to use OnPush change detection strategy for this. See http://blog.angular-university.io/onpush-change-detection-how-it-works/

Declare this Timer utility above your @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');
  }
}

Add this inside your component class:

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.
}

Note that Angular rendering is separate from the browser rendering (painting) on the screen. That takes time too. When you see javascript (yellow) with lots of "checkAndUpdateView" and "callViewAction" calls in the Chrome Timeline Tool (javascript developer console -> performance -> record) that is Angular rendering happening. When you see purple in the Chrome Timeline Tool, labelled "rendering", that is actual browser rendering.