如何在Angular中测试渲染速度

时间:2014-08-14 15:40:43

标签: javascript angularjs performance performance-testing

我们正在构建一个Angular应用,我们正试图弄清楚如何获得渲染各种页面需要多长时间的基准。我已经阅读了performance.timing here,但这似乎只适用于非单页应用,因为当我在应用中导航到新视图时,时序数字不会改变。< / p>

理想情况下,我们可以插入一些代码来获取各种视图的渲染时间,并将其发布到我们的Big Query服务中。

有关如何在Angular应用中获取视图的时序信息的任何想法吗?

编辑:

更具体地说,您将转到加载大型重复列表的路径(这对于性能而言不是最佳),并且窗口在实际呈现列表中的项之前有很长的延迟。我们希望了解从大空白视图到呈现列表中的项目所需的时间。

3 个答案:

答案 0 :(得分:8)

在做了一些实验之后,我找到了一种方法来估算视图渲染的时间长度。

情景:

  1. 路由到Angular应用程序中的页面
  2. 进行AJAX调用以获取冗长的项目列表
  3. 列出商品列表,转入ng-repeat ul
  4. 查看呈现的列表
  5. 在Angular应用中,ng-repeat是一个臭名昭着的性能杀手,但它非常方便。 Here's a discussion on the performancehere.

    让我们说我们希望得到从#3到#4所需时间的近似值,因为测试AJAX调用性能非常简单。

    这里有一些背景信息:

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

    在Angular控制器内部:

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

    @runTarm,$routeChangeStart$routeChangeSuccess$viewContentLoaded提到的事件会在路由加载后立即触发,但在DOM呈现项目之前,所以他们不会#39解决问题。但是,通过实验,我发现一旦AJAX回调完成并设置$scope.items,Angular就会开始处理items并准备插入ng-repeat ul的阻止操作DOM。因此,如果您在AJAX调用完成后得到时间,并在回调中指定的setTimeout中再次获得时间,则setTimeout回调将排队等待Angular完成转发器进程并在DOM渲染之前的瞬间获得时间,为您提供最接近渲染时间的近似值。它不是真正的渲染时间,但对我们来说,缓慢的部分不是DOM正在做它的工作,而是Angular,这是我们正在寻找的。

    以下是经修订的示例:

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

答案 1 :(得分:2)

TypeScript / Angular(2+)回答:

要对角度渲染组件树所花费的时间进行基准测试,请在更改检测之前和之后进行测量。这将计算Angular创建所有子组件并评估ngIf s / ngFor等所花费的时间。

有时,当变化检测运行时,什么都不会改变,定时间隔会很小。只需寻找最长的时间间隔,这可能是所有工作发生的地方。此外,最好使用OnPush更改检测策略。见http://blog.angular-university.io/onpush-change-detection-how-it-works/

将此计时器实用程序声明在@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');
  }
}

在组件类中添加

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

请注意,角度渲染与屏幕上的浏览器渲染(绘画)分开。这也需要时间。当您在Chrome时间线工具(javascript开发者控制台 - &gt;效果 - &gt;记录)中看到javascript(黄色),其中包含大量“checkAndUpdateView”和“callViewAction”调用,这是Angular渲染的发生。当你在Chrome时间线工具中看到紫色标记为“渲染”时,这就是实际的浏览器渲染。

答案 2 :(得分:0)

尝试使用开源Chrome插件Angular-performance,您可以监控Angular应用程序中的摘要时间:https://github.com/Linkurious/angular-performance