Angular4のパフォーマンス最適化の操作方法

php中世界最好的语言
リリース: 2018-06-02 11:22:53
オリジナル
1162 人が閲覧しました

今回は、Angular4パフォーマンス最適化の操作方法と、Angular4パフォーマンス最適化を操作する際の注意点について、実際の事例を交えて紹介します。

概要

Angular 4 におけるダーティ値の検出は古いトピックであり、このモデルを理解することが Angular のパフォーマンス最適化の基礎となります。したがって、今日は Angular 4 のダーティ値検出の原理について説明し、パフォーマンスを最適化するためのヒントをいくつか見ていきます。

エントリー ポイント - Zone.js

Angular 4 は MVVM フレームワークです。データモデル (Model) がビューモデル (ViewModel) に変換された後、View (View) にバインドされ、肉眼で見えるページにレンダリングされます。したがって、データ モデルが変更される時点を発見することが、ページを更新してダーティ値検出を呼び出すための鍵となります。

分析の結果、エンジニアはデータの変更がマクロタスクやマイクロタスクなどの非同期イベントによって引き起こされることが多いことを発見しました。したがって、ブラウザ内のすべての非同期 API を書き換えることにより、データの変更をソースから効果的に監視できます。 Zone.js はそんなモンキースクリプト(Monkey Patch)です。 Angular 4 は、カスタマイズされたゾーン (NgZone) を使用します。これは、データが変更される可能性があり、ビュー内のデータを更新する必要があることを Angular に通知します (ダーティ値の検出)。

ダーティ値検出(変更検出)

ダーティ値検出の基本原理は、古い値を保存し、検出する際に現時点の新しい値と古い値を比較することです。それらが等しい場合、変更はありません。そうでない場合、変更が検出され、ビューを更新する必要があります。

Angular 4 はページを複数のコンポーネントに分割してコンポーネント ツリーを形成します。ダーティ値検出に入ると、ルートコンポーネントから上から下へ検出が行われます。 Angular には、Default と OnPush という 2 つの戦略があります。これらはコンポーネント上で構成され、ダーティ値検出時のさまざまな動作を決定します。

Default - デフォルト戦略

ChangeDetectionStrategy.Default。また、データを変更する可能性のあるイベントが発生すると、このコンポーネントが常にテストされることも意味します。

ダーティ値検出の動作は、基本的に次のステップとして理解できます。 1) サブコンポーネントにバインドされているプロパティを更新します。2) サブコンポーネントの NgDoCheck および NgOnChangeslifecycleフック (ライフサイクル フック) を呼び出します。3) 独自の DOM を更新します。4) サブコンポーネントのダーティ値を検出します。これはルートコンポーネントから始まる再帰方程式です。

// This is not Angular code
function changeDetection(component) {
 updateProperties(component.children);
 component.children.forEach(child => {
  child.NgDoCheck();
  child.NgOnChanges();
 };
 updateDom(component);
 component.children.forEach(child => changeDetection(child));
}
ログイン後にコピー

私たち開発者は、DOM の更新順序と NgDoCheck と NgOnChanges の呼び出し順序に細心の注意を払います。次のことがわかります:

  1. DOM 更新は深さ優先です

  2. NgDoCheck と NgOnChanges は深さ優先ではありません (深さ優先でもありません)

OnPush - 単一の検出戦略

ChangeDetectionStrategy.OnPush。このコンポーネントは、入力プロパティが変更されたとき (OnPush) にのみ検出されます。したがって、入力が変化しない場合、それは初期化中にのみ検出され、単一検出とも呼ばれます。その他の動作はデフォルトと一致します。

OnPush は入力への参照のみを検出することに注意してください。 Input オブジェクト のプロパティ変更は、現在のコンポーネントのダーティ値検出をトリガーしません。

OnPush 戦略はパフォーマンスを向上させますが、バグのホットスポットでもあります。多くの場合、解決策は入力を不変形式に変換し、入力の参照を強制的に変更することです。

ヒント

データバインディング

Angularには3つの合法的なデータバインディングメソッドがありますが、それらのパフォーマンスは異なります。

データを直接バインドする

<ul>
 <li *ngFor="let item of arr">
  <span>Name {{item.name}}</span>
  <span>Classes {{item.classes}}</span><!-- Binding a data directly. -->
 </li>
</ul>
ログイン後にコピー

ほとんどの場合、これが最適な実行方法です。

関数呼び出し結果をバインドする

<ul>
 <li *ngFor="let item of arr">
  <span>Name {{item.name}}</span>
  <span>Classes {{classes(item)}}</span><!-- Binding an attribute to a method. The classes would be called in every change detection cycle -->
 </li>
</ul>
ログイン後にコピー

各ダーティ値検出プロセスで、クラス方程式を 1 回呼び出す必要があります。ユーザーがページをスクロールし、複数のマクロタスクが生成され、各マクロタスクが少なくとも 1 つのダーティ値チェックを実行すると想像してください。特別な必要がない場合は、この使用方法はできるだけ避けてください。

Bind data+pipe

<ul>
 <li *ngFor="let item of instructorList">
  <span>Name {{item.name}}</span>
  <span>Classes {{item | classPipe}}</span><!-- Binding data with a pipe -->
 </li>
</ul>
ログイン後にコピー

ダーティ値検出classPipeが呼び出されるたびに行うバインディング関数と同様です。ただし、Angular はパイプを最適化し、キャッシュを追加しました。項目が前回と等しい場合は、結果が直接返されます。

NGFor

多数情况下,NgFor应该伴随trackBy方程使用。否则,每次脏值检测过程中,NgFor会把列表里每一项都执行更新DOM操作。

@Component({
 selector: 'my-app',
 template: `
  <ul>
   <li *ngFor="let item of collection;trackBy: trackByFn">{{item.id}}</li>
  </ul>
  <button (click)="getItems()">Refresh items</button>
 `,
})
export class App {
 collection;
 constructor() {
  this.collection = [{id: 1}, {id: 2}, {id: 3}];
 }
  
 getItems() {
  this.collection = this.getItemsFromServer();
 }
  
 getItemsFromServer() {
  return [{id: 1}, {id: 2}, {id: 3}, {id: 4}];
 }
  
 trackByFn(index, item) {
  return index;
 }
}
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue怎样实现beforeEnter钩子函数

怎样使用vue实现选项卡及选项卡切换效果

以上がAngular4のパフォーマンス最適化の操作方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート