3

私は AngularJS 1.x と Angular 2 をいじって、パフォーマンスを比較しようとしました。

これは、Angular 1.x の「マイナス面」を示すPlunkrです。スコープに存在する要素が多すぎると、入力フィールドを編集するときに入力フィールドのレンダリングに遅延が発生することに気付くでしょう。フレームワークは、変更された可能性のあるイベントを検出するたびに、スコープ上のすべての要素をチェックするからです。

最初の Plunkr (html) からの抜粋:

<body ng-app="myApp">
<div ng-controller="myCtrl">
  <input ng-model ="name"></input>
  Hello, {{name}}!
  <button ng-click="generateFields()">
    Generate 5000 elements
  </button>
  {{list}}
</div>

最初の Plunkr (js) からの抜粋:

myApp.controller('myCtrl', function($scope) {
$scope.name = 'name';
$scope.list = [];

$scope.generateFields = function(){
    for(i=0; i<5000;i++){
    $scope.list.push(i);
  }
}

});

このPlunkrでは、同様のサンプルを Angular 2 で書いています。ラグはまったくないようです。これはAngular 2でどのように解決されますか? フレームワークは、入力フィールドのみが変更されたことを何らかの方法で認識していますか?それとも、VM に最適化された変更検出機能により、ダーティ チェックの実行が高速になっているだけですか?

2 番目の Plunkr からの抜粋:

@Component({
 selector: 'my-app',
  providers: [],
  template: `
    <div>
      <div>{{myProp}}</div>
      <input [(ngModel)]="myProp" />
      <button (click)="generateFields()">Generate</button>
      <div>{{myList}}</div>
    </div>
  `,
  directives: []
})
export class App {
  constructor() {
  }

  myProp :string = "Change me!";
  myList :any = [];

  generateFields(){
     for (var i = 1; i < 5000; i++)
     {       
          this.myList.push(i);
     }

    console.log("fields generated");
  }
}
4

2 に答える 2

1

VM に最適化された変更検出機能により、ダーティ チェックの実行が高速になるだけですか?

Angular 2 での変更検出は Angular 1 とは完全に異なるため、言うのは難しいです。同じことは、ダーティ チェック テンプレート バインディングの (論理的な) 概念だけだと思います。最も可能性が高いのは、Angular 2 がコンポーネントごとに作成する変更検出オブジェクトで生成するモノモーフィック (VM フレンドリー/最適化) コード ( Angular ブログthinkram ブログV.Savkin トーク) です。

更新したばかりの 2 番目の plunkr をご覧ください。これで、リストを入力パラメーターとして取得する子コンポーネントができました。これを導入するとすぐに、Angular はデフォルトの CD 戦略のために配列の詳細なチェックを行うことを余儀なくされました。つまり、十分な要素を生成するとすぐにパフォーマンスが大幅に低下しました。ただし、angular 1 よりもかなり高速です。要するに、デフォルトの CD 戦略の場合、入力パラメーターは変更について詳細にチェックされますが、コンポーネントの「ローカル」変数はチェックされません。

...そして、プロパティバインディングは別のバインディング式であるため、Angular はデフォルトで詳細なチェックを行います。

テンプレート バインディングに反復可能なものが含まれている場合[myList]="myList"(例:開発モードのみ)、変更検出は実際にすべての (例: myList) 項目を繰り返し処理し、それらを比較します。NgFor ループや、子コンポーネントの各要素へのテンプレート バインディング。looseIdentical()これは、本番モードで実行されるチェック (つまり、===チェック、したがって参照チェック) とは大きく異なります。あなたが発見したように、非常に大きなイテラブルの場合、これは開発モードでのみパフォーマンスに影響を与える可能性があります。

この「devMode のみのディープ チェック」に関する詳細な説明については、https: //stackoverflow.com/a/37356950/215945 を参照してください。

于 2016-06-07T14:56:15.020 に答える