How to check rendering speed in Angular

We are creating an Angular application, and we are trying to figure out how to get some guidelines regarding how long it takes to render different pages. I read about performance.timing here , but it seems useful only for applications with more than one page, since when I switch to new views in our application, the time numbers do not change.

Ideally, we could insert some kind of code that gets the rendering time for various views and sends it to our our big request.

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

EDIT:

In particular, you go to a route that loads a large ng-repeat list (which is not optimal for performance), and the window has a long delay before it actually displays the items in the list. We would like to see how long it takes to move from a large empty view to rendering items in a list.

+6
source share
3 answers

After some experimentation, I found a way to get a rough idea of ​​how long it takes to render.

Scenario:

  • The route to the page in the Angular application
  • AJAX call to get a long list of items
  • Take a list of items, go to ng-repeat ul
  • View the displayed list

In an Angular application, ng-repeat is a notorious manufacturer, but it is very convenient. Performance is discussed here, and here.

Let's say that we want to get the approximate time needed to go from # 3 to # 4, since testing AJAX call performance is pretty simple.

Here is the context:

 <ul> <li ng-repeat="item in items"> {{item.name}} <!-- More content here --> </li> </ul> 

And inside the Angular controller:

 // 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); }); 

The events mentioned by @runTarm, $routeChangeStart , $routeChangeSuccess and $viewContentLoaded triggered as soon as the route is loaded, but before the DOM displays the elements, so they do not solve the problem. However, through experimentation, I found that after completing the AJAX callback and typing $scope.items , Angular starts the items processing lock operation and prepares ng-repeat ul for insertion into the DOM. That way, if you get the time after the AJAX call ends and get the time again in setTimeout specified in the callback, the setTimeout callback will be queued until Angular is executed using the follower process and you get the time spent for a split second before the DOM displays, giving you the closest approximation for the rendering time. This will not be the actual rendering time, but the slow part for us is not the DOM that works, but the Angular that we are looking for to measure.

Here is an example:

 // 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); }); 
+7
source

TypeScript / Angular (2+) answer:

To evaluate the time spent in Angular rendering a component tree, measure before and after detecting changes. It will take the time that Angular takes to create all child components and evaluate ngIf / ngFor , etc.

Sometimes, when change detection starts, nothing changes and the time interval is small. Just find the longest time interval and probably where everything works. Also, it is best to use the OnPush change detection strategy for this. See http://blog.angular-university.io/onpush-change-detection-how-it-works/

Declare this Timer utility over 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 to 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 browser rendering (painting) on ​​the screen. It takes time. When you see javascript (yellow) with a lot of calls to "checkAndUpdateView" and "callViewAction" in the Chrome history tool (javascript developer console β†’ performance β†’), that is, Angular execution. When you see purple in the Chrome Timeline Tool, labeled β€œrendering,” this is the actual display of the browser.

+1
source

Try the open source Chrome Angular -performance plugin, you can control the digest time in Angular apps: https://github.com/Linkurious/angular-performance

0
source

Source: https://habr.com/ru/post/973828/


All Articles