Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?

青灯夜游
リリース: 2022-05-11 14:11:32
転載
2616 人が閲覧しました

変化検出とは何ですか?次の記事では、Angular の変更検出メカニズムを理解し、変更検出がどのように機能するかについて説明し、Angular 変更検出のパフォーマンス最適化方法を紹介します。

Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?

#変更検出 (Change Detection) とは何ですか?

#変更検出の概念

コンポーネント内のデータのステータスが変化した後、それに応じてビューを更新する必要があります。ビューとデータを同期するこのメカニズムは、変更検出と呼ばれます。 [関連チュートリアルの推奨事項: "

angular チュートリアル"]

変更検出のトリガー タイミング

非同期操作が発生している限り (イベント、タイマー) 、 XHR )、Angular は状態が変更された可能性があると判断し、変更検出を実行します。

    イベント::
  • クリック、マウスオーバー、マウスアウト、キーアップ、キーダウン、およびその他のブラウザ イベント;
  • タイマー:
  • setTimeout/setInterval;
  • XHR:
  • 各種ご要望等
変更検出は非同期操作で実行されるため、Angular はどのようにして非同期リクエストをサブスクライブし、変更検出を実行するのでしょうか?

ここでは、

NgZone とそのフォーク オブジェクト Zone.js について説明します。

Zone.js は、ブラウザーでの非同期アクティビティをカプセル化してインターセプトするために使用され、非同期ライフサイクル フック統合された非同期エラー処理メカニズムも提供します。

Zone.js は、Monkey Patching を使用して、ブラウザ内の一般的なメソッドと要素 (setTimeout など) をインターセプトします。 HTMLElement.prototype.onclick。 Angular は、起動時に Zone.js を利用して、いくつかの低レベルのブラウザ API にパッチを適用して、非同期イベントをキャプチャし、キャプチャ時間後に変更検出を呼び出します。

Angular は

Zone.js をフォークし、独自のゾーン NgZone を展開して、アプリケーション内のすべての非同期操作がこのゾーンで実行されるようにします。

Angular の変更検出はどのように機能しますか?

Angualr は、コンポーネントごとに変更検出器

changeDetector を生成し、コンポーネントの変更ステータスを記録します。

Angular アプリケーションを作成した後、Angular は

ApplicationRef のインスタンスも作成します。このインスタンスは、現在作成中の Angular アプリケーションのインスタンスを表します。 ApplicationRef 作成されると、ngZone の onMicrotaskEmpty イベントにサブスクライブされ、すべてのマイクロタスクが完了した後、すべてのビューの detectChanges() が呼び出されて実行されます。変化検出です。

変更検出の実行順序

  • すべてのサブサブコンポーネントにバインドされているプロパティを更新します

  • すべてのサブコンポーネントのライフサイクル フック OnChanges、OnInit、DoCheck、AfterContentInit を呼び出します。

  • 現在のコンポーネントの DOM を更新します。

  • 変更検出を呼び出します。サブコンポーネントの

  • すべてのサブコンポーネントのライフ サイクル フック ngAfterViewInit を呼び出す

たとえば、次のような場合にこの種のエラーが発生する可能性があります。私たちは開発モードです :

Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?

これは、変更検出はルート コンポーネントから開始して上から下へ、最後のコンポーネントまで各コンポーネントの変更検出を実行するためです。コンポーネントが安定状態に達します。次の変更が検出されるまで、子孫コンポーネントは親コンポーネントのプロパティを変更できません。

ケース 1 開発モードでは、Angular は 二次検出を実行します (本番環境で enableProdMode()## を呼び出します #、検出数は 1 に減ります)。 ステップ 4 が完了した後、子孫コンポーネントで親コンポーネントのプロパティを変更すると、Angular が 2 回目の検出を実行して 2 つの値が矛盾していることが判明すると、上記のエラーが発生します。

ケース 2 親コンポーネントがプロパティを子コンポーネントにバインドしている限り、OnChanges、OnInit、DoCheck、AfterContentInit、AfterViewInit の実行に関係なく、サイクルフック内の次のコードもエラーを報告します。

// #parent
{{data}}
<child [data]="data"></child>

// in child component ts, execute:
this.parent.data = &#39;new Value&#39;;
ログイン後にコピー

変更検出の実行戦略

  • ##デフォルト戦略#

    このデフォルトの戦略は、イベント (ユーザー イベント、タイマー、XHR、Promise など) が変更検出をトリガーするたびに、コンポーネント ツリー内のすべてのコンポーネントを上から下までチェックします。コンポーネントの依存関係について何の仮定も行わないこの保守的なチェック方法は、Dirty Check と呼ばれます。この戦略は、適用するコンポーネントが多すぎると、アプリケーションのパフォーマンスに影響を与えます。

  • #OnPush 戦略

    コンポーネント デコレータを変更する

    changeDetection、OnPush 戦略に設定した後、Angular は変更検出をトリガーするたびに、このコンポーネントとこのコンポーネントのすべてのサブコンポーネントの変更検出をスキップします。

    OnPush 戦略では、次の状況のみがコンポーネント変更検出をトリガーします:

    • 入力値 (@Input) の変更 (入力に入力された値は新しい参照である必要があります)
    • 現在のコンポーネントまたはサブコンポーネントの 1 つがイベント をトリガーしました (ただし、onPush 戦略では、次の操作は変更検出をトリガーしません)
      • setTimeout()
      • setInterval()
      • Promise.resolve().then()
      • this.http.get('...').subscribe()
    • 変更検出を手動でトリガーする (各コンポーネントはコンポーネント ビュー ChangeDetectorRef に関連付けられます)
      • detectChanges(): 現在のコンポーネントとサブコンポーネントの変更検出をトリガーします
      • ##markForCheck(): 変更検出はトリガーされませんが、現在の OnPush コンポーネントと、親コンポーネントが OnPush であるすべてのコンポーネントが検出ステータスを必要としてマークされます #、現在または次の変更検出サイクルで検出します
      • ApplicationRef.tick()
      • : コンポーネントの変更検出に従ってアプリケーション全体の変更検出をトリガーします戦略
      Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?非同期パイプ
  • での変更検出についてはどうですか角度の最適化?

コンポーネントはデフォルトで Default Strategy

を実行するため、非同期操作によりコンポーネント番号全体の上から下へのチェックがトリガーされます。たとえ Angular チームがパフォーマンスの向上を続け、ミリ秒以内に数百の検出を完了できたとしても、アプリケーションが数百または数千のコンポーネントに拡張すると、巨大なコンポーネント ツリーに対応する変更検出がパフォーマンスのボトルネックに達します。

この時点で、不必要なテストの分析と削減を開始する必要があります。

検査数を減らす方法

    地域汚染
  • 一般的に、私たちは生きています。チャート クラス ライブラリの初期化などのサイクル フックでサードパーティ ライブラリを使用する場合、requestAnimationRequest/setTimeout/addEventListener が付属します。初期化メソッドを NgZone## の

    runOutsideAngular

    メソッドに書き込むことができます。 #。

Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?#OnPush 戦略

  • 更新操作を含まないビューは、コンポーネントを終了し、onPush 戦略を使用して更新を通知することでビューを更新します (上記の

    変更検出の実行戦略 セクションを参照)。

{{function(data)}}## の代わりに Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?純粋なパイプ

を使用してください
  • #HTML ファイル内で

    {{function(data)}} という記述方法では、変更検出が発生するたびにすべての値が再計算されます。 (?: 1,000 項目のリストがある場合、データは 1 つだけ変更されますが、更新する必要のない他の 999 個のデータも再計算されます。)このとき、パイプメソッドを使用できます。変更された値のみが操作をトリガーし、ビューの一部を更新します。

大量のデータのレンダリングに直面して、データをリクエストするには仮想スクロール/ページングを選択してください

Angular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?

上記の 4 点の解決策は、
    Angular チーム
  • のビデオ紹介から引用したもので、ビデオでは Angular devtool を使用して回数を計算することで問題を分析および解決しています。したがって、Angular 9 をお持ちの場合は、Angular devtool を起動して実行する方法を学習してください。

插件:Angular devtool使用介绍

  • Angular 9+, 支持Ivy。
  • Guide下载地址
  • 保证运行环境为开发环境
    // environment.dev.ts
    ...
        production: false
    ...
    ログイン後にコピー
  • angular.json > dev配置项 > "optimization": false
    projects > your-project-name > architect > build > configurations > dev > "optimization": false
    ログイン後にコピー

    更多编程相关知识,请访问:编程教学!!

    以上がAngular の変更検出メカニズムとパフォーマンスを最適化する方法の簡単な分析?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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