ホームページ > 記事 > ウェブフロントエンド > Angular4 のパフォーマンス最適化方法のまとめ
今回は、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 の呼び出し順序に細心の注意を払います。
DOM 更新は深さ優先である
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; } }
Reference
He who thinks change detection is depth-first and he who thinks it's breadth-first are both usually right
Angular Runtime Performance Guide
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がAngular4 のパフォーマンス最適化方法のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。