ホームページ ウェブフロントエンド jsチュートリアル Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

Oct 11, 2021 am 09:55 AM
angular パフォーマンスの最適化

Angular を最適化するにはどうすればよいですか?次の記事では、Angular でのパフォーマンスの最適化について説明します。お役に立てば幸いです。

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

この記事では Angular のパフォーマンスの最適化について説明し、主にランタイムに関連する最適化について紹介します。最適化の方法について話す前に、まずどのようなページにパフォーマンスの問題があるのか​​を明確にする必要があります。良いパフォーマンスの尺度は何ですか?パフォーマンス最適化の背後にある原理は何ですか?これらの質問に興味がある場合は、読み続けてください。 [関連チュートリアルの推奨事項: "angular チュートリアル"]

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

変更検出メカニズム# #ネットワーク送信の最適化とは異なり、ランタイムの最適化では、Angular の動作メカニズムと、パフォーマンスの問題を効果的に回避するコードの作成方法 (ベスト プラクティス) に重点が置かれます。 Angular の動作メカニズムを理解するには、まずその変更検出メカニズム (ダーティ チェックとも呼ばれる)、つまり状態の変化をビューに再レンダリングする方法を理解する必要があります。コンポーネントのステータスの変化をビューにどのように反映するかは、3 つのフロントエンド フレームワークすべてが解決する必要がある問題でもあります。さまざまなフレームワークのソリューションは同様のアイデアを持っていますが、それぞれ独自の特徴もあります。

まず第一に、Vue と React は両方とも仮想 DOM を使用してビューの更新を実装しますが、特定の実装にはまだ違いがあります:

React の場合:

    setState
  • または

    forceUpdate を使用して render メソッドをトリガーし、ビューを更新します。

    親コンポーネントはビューを更新します。また、
  • re-render
  • サブコンポーネント

    Vue の場合:

Vue がトラバースするかどうかも決定します。
    data
  • オブジェクトのすべてのプロパティ。

    Object.defineProperty を使用して、これらすべてのプロパティをラップされた getter および setter# に変換します。 ##各コンポーネント インスタンスには、対応する

    watcher
  • インスタンス オブジェクトがあり、コンポーネントのレンダリング プロセス中にプロパティを依存関係として記録します。依存関係
  • setter

    が呼び出されると、関連するコンポーネントを更新できるように、watcher に再計算するよう通知します。

  • そして、Angular はこれを次のように実行します。 Zone .js を導入すると、非同期操作用に API にパッチが適用され、変更検出用のトリガーがリッスンされます。 Zone.js の原理は、前の 記事 で詳しく紹介されています。簡単に言うと、Zone.js は、モンキー パッチを適用することで、ブラウザまたはノード内のすべての非同期 API を強力にカプセル化し、置き換えます。 たとえば、ブラウザの

    setTimeout
  • :
let originalSetTimeout = window.setTimeout;

window.setTimeout = function(callback, delay) {
  return originalSetTimeout(Zone.current.wrap(callback),  delay);
}

Zone.prototype.wrap = function(callback) {
  // 获取当前的 Zone
  let capturedZone = this;

  return function() {
    return capturedZone.runGuarded(callback, this, arguments);
  };
};
ログイン後にコピー

または Promise.then メソッド:

let originalPromiseThen = Promise.prototype.then;

// NOTE: 这里做了简化,实际上 then 可以接受更多参数
Promise.prototype.then = function(callback) {
  // 获取当前的 Zone
  let capturedZone = Zone.current;
  
  function wrappedCallback() {
    return capturedZone.run(callback, this, arguments);
  };
  
  // 触发原来的回调在 capturedZone 中
  return originalPromiseThen.call(this, [wrappedCallback]);
};
ログイン後にコピー

Zone.js はloading の場合、すべての非同期インターフェイスがカプセル化されます。したがって、Zone.js で実行されるすべての非同期メソッドはタスクとして扱われ、タスクによって均一に監視され、非同期タスクの実行の前後または特定の段階で追加の操作を実行するための対応するフック関数 (フック) が提供されます。 。したがって、Zone.js では、ログ記録、パフォーマンスの監視、非同期コールバック実行のタイミング制御などの機能を簡単に実装できます。 これらのフック関数 (フック) は、

Zone.fork()

メソッドを通じて設定できます。詳細については、次の設定を参照してください: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>Zone.current.fork(zoneSpec) // zoneSpec 的类型是 ZoneSpec // 只有 name 是必选项,其他可选 interface ZoneSpec { name: string; // zone 的名称,一般用于调试 Zones 时使用 properties?: { [key: string]: any; } ; // zone 可以附加的一些数据,通过 Zone.get(&amp;#39;key&amp;#39;) 可以获取 onFork: Function; // 当 zone 被 forked,触发该函数 onIntercept?: Function; // 对所有回调进行拦截 onInvoke?: Function; // 当回调被调用时,触发该函数 onHandleError?: Function; // 对异常进行统一处理 onScheduleTask?: Function; // 当任务进行调度时,触发该函数 onInvokeTask?: Function; // 当触发任务执行时,触发该函数 onCancelTask?: Function; // 当任务被取消时,触发该函数 onHasTask?: Function; // 通知任务队列的状态改变 }</pre><div class="contentsignin">ログイン後にコピー</div></div>Give one

onInvoke の簡単な例

:

let logZone = Zone.current.fork({ 
  name: &#39;logZone&#39;,
  onInvoke: function(parentZoneDelegate, currentZone, targetZone, delegate, applyThis, applyArgs, source) {
    console.log(targetZone.name, &#39;enter&#39;);
    parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source)
    console.log(targetZone.name, &#39;leave&#39;); }
});

logZone.run(function myApp() {
    console.log(Zone.current.name, &#39;queue promise&#39;);
    Promise.resolve(&#39;OK&#39;).then((value) => {console.log(Zone.current.name, &#39;Promise&#39;, value)
  });
});
ログイン後にコピー

最終的な実行結果:

Zone.js の原理を理解した後、ソースを読んでください。 Angular のコードを見ると、非同期メソッドまたはイベントが呼び出されるたびに変更検出を実装するために Angular で Zone.js が使用されていることがわかります。それはおおよそ次のとおりです。

まず、

applicatoin_ref.ts

ファイル内で、

ApplicationRefAngular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析 がビルドされるときに、マイクロタスク キューが空であるというコールバック イベントをサブスクライブします。

tick

メソッド (つまり、変更検出) を呼び出します:

2 番目に、checkStable メソッドでは、マイクロタスク キューが空になったときに onMicrotaskEmpty イベントがトリガーされると判断されます (組み合わせて、変更検出をトリガーするのと同等です) ):

2-Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

最後に、checkStable メソッドの呼び出しをトリガーできる場所は、Zone.js の 3 つのフック関数内です。 onInvokeonInvokeTaskonHasTask:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

#例: onHasTask—— ZoneTask の有無が検出されたときにトリガーされるフック:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

さらに、Zone.js の非同期タスクは次のとおりです。 3 つのカテゴリに分かれています:

マイクロ タスク: Promise などによって作成されました。nativePromise は前に必要です現在のイベント ループの最後が実行され、パッチが適用された Promise もイベント ループの終了前に実行されます。

マクロ タスク: setTimeout などで作成され、nativesetTimeout が処理時間になります。

イベント タスク: addEventListener などによって作成されます。これらの タスクは複数回トリガーされる場合もあれば、まったくトリガーされない場合もあります。

実際、ブラウザの観点からは、イベント タスクは実際にはマクロ タスクとみなすことができます。つまり、すべてのイベントまたは非同期 API はマクロ タスクまたはマイクロ タスクとして理解できます。それらのタスクの 1 つとその実行順序は、前の 記事 で詳しく分析されています。簡単に言うと:

(1) メインスレッドが実行された後、最初にマイクロプロセッサがチェックされます。 . タスクキューにまだ実行すべきタスクがあるかどうか

(2) 初回ポーリング終了後、マクロタスクキューにまだ実行すべきタスクがあるかどうかを確認します。マイクロ タスク リストに実行するタスクがまだあるかどうかを確認し、このプロセスが繰り返されます。

#パフォーマンス最適化の原則

#最も直感的なものページのパフォーマンスを判断する方法は、ページの応答がスムーズで応答性が高いかどうかを確認することです。ページ応答は本質的に、ページ状態の変更をページに再レンダリングするプロセスです。比較的マクロな観点から見ると、Angular の変更検出は実際にはイベント応答サイクル全体の一部にすぎません。ユーザーとページ間のすべてのインタラクションはイベントによってトリガーされ、応答プロセス全体は大まかに次のとおりです:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

ページの応答速度の最適化を検討する場合は、次のことから始めることができます。各ステージ:

(1) トリガー イベント ステージの場合、イベントのトリガーを減らして、変更検出と再レンダリングの全体的な数を減らすことができます

(2) イベント ハンドラーの場合実行ロジックステージでは、複雑なコードを最適化できる 実行時間を短縮するためのロジック

(3) 変更検出検出データバインディングおよび DOM 更新ステージでは、変更検出とテンプレートデータの計算数を削減して、レンダリング時間

(4) ブラウザのレンダリング段階では、別のブラウザの使用またはハードウェア構成の改善を検討する必要がある場合があります。

第 2 段階と第 4 段階はここにあります非同期用に上記の Angular と組み合わせると、第 1 段階と第 3 段階の最適化方法でタスクの分類をさらに明確にすることができます:

(1) マクロ タスクのマージ リクエストの場合は、次のようにしてください。ティック数を減らす

(2) ティックをマージするマイクロタスクの場合

(3) イベントタスクのイベントトリガーと登録イベントを減らす

(4) ティックは次のように分割されます2 つのフェーズ: チェックとレンダリング。チェック フェーズでの計算と不要なレンダリングを削減します

前面有提到,大多数情况通过观察页面是否流畅可以判断页面的是否存在性能问题。虽然这种方式简单、直观,但也相对主观,并非是通过精确的数字反映页面的性能到底如何。换言之,我们需要用一个更加有效、精确的指标来衡量什么样的页面才是具备良好性能的。而 Angular 官方也提供了相应的方案,可以通过开启 Angular 的调试工具,来实现对变更检测循环(完成的 tick)的时长监控。

首先,需要使用 Angular 提供的 enableDebugTools 方法,如下:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

之后只需要在浏览器的控制台中输入 ng.profiler.timeChangeDetection() ,即可看到当前页面的平均变更检测时间:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

从上面可以看出,执行了 692 次变更检测循环(完整的事件响应周期)的平均时间为 0.72 毫秒。如果多运行几次,你会发现每次运行的总次数是不一样、随机的。

官方提供了这样一个判断标准:理想情况下,分析器打印出的时长(单次变更检测循环的时间)应该远低于单个动画帧的时间(16 毫秒)。一般这个时长保持在 3 毫秒下,则说明当前页面的变更检测循环的性能是比较好的。如果超过了这个时长,则就可以结合 Angular 的变更检测机制分析一下是否存在重复的模板计算和变更检测。

性能优化方案

在理解 Angular 优化原理的基础上,我们就可以更有针对性地去进行相应的性能优化:

(1)针对异步任务 ——减少变更检测的次数

  • 使用 NgZone 的 runOutsideAngular 方法执行异步接口
  • 手动触发 Angular 的变更检测

(2)针对 Event Task —— 减少变更检测的次数

  • 将 input 之类的事件换成触发频率更低的事件
  • 对 input valueChanges 事件做的防抖动处理,并不能减少变更检测的次数

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

如上图,防抖动处理只是保证了代码逻辑不会重复运行,但是 valueChanges 的事件却随着 value 的改变而触发(改变几次,就触发几次),而只要有事件触发就会相应触发变更检测。

(3)使用 Pipe ——减少变更检测中的计算次数

  • 将 pipe 定义为 pure pipe(@Pipe 默认是 pure pipe,因此也可以不用显示地设置 pure: true

    import { Piep, PipeTransform } from &#39;@angular/core&#39;;
    
    @Pipe({
      name: &#39;gender&#39;,
      pure,
    })
    export class GenderPiep implements PipeTransform {
      transform(value: string): string {
        if (value === &#39;M&#39;) return &#39;男&#39;;
        if (value === &#39;W&#39;) return &#39;女&#39;;
        return &#39;&#39;;
      }
    }
    ログイン後にコピー

关于 Pure/ImPure Pipe:

  • Pure Pipe: 如果传入 Pipe 的参数没有改变,则会直接返回之前一次的计算结果

  • ImPure Pipe: 每一次变更检测都会重新运行 Pipe 内部的逻辑并返回结果。(简单来说, ImPure Pipe 就等价于普通的 formattedFunction,如果一个页面触发了多次的变更检测,那么 ImPure Pipe 的逻辑就会执行多次)

(4)针对组件 ——减少不必要的变更检测

  • 组件使用 onPush 模式
    • 只有输入属性发生变化时,该组件才会检测
    • 只有该组件或者其子组件中的 DOM 事件触发时,才会触发检测
    • 非 DOM 事件的其他异步事件,只能手动触发检测
    • 声明了 onPush 的子组件,如果输入属性未变化,就不会去做计算和更新
@Component({
  ...
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class XXXComponent {
	....
}
ログイン後にコピー

在 Angular 中 显示的设置 @ComponentchangeDetection 为  ChangeDetectionStrategy.OnPush 即开启 onPush 模式(默认不开启),用 OnPush 可以跳过某个组件或者某个父组件以及它下面所有子组件的变化检测,如下所示:

Angular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析

(5)针对模板 ——减少不必要的计算和渲染

  • リストのループレンダリングには trackBy を使用します。
  • キャッシュされた値をできるだけ使用し、メソッド呼び出しや属性呼び出しの使用を避けます。
  • 本当に関数を呼び出す必要があるテンプレートと、複数の呼び出しの場合は、テンプレート キャッシュ
  • ngIf を使用してコンポーネントの表示を制御し、コンポーネントが呼び出される場所に配置できます。
(6) その他のコーディング最適化の提案

プロセス制御に try/catch を使用しないでください。これにより、多くの時間が消費されます (大量のスタックが記録されます)。
  • 過剰なアニメーションはページの読み込み遅延を引き起こします
  • 長いリストには仮想スクロールを使用できます
  • プリロード モジュールの読み込みをできるだけ遅らせます。ブラウザの同時 http リクエスト スレッド数には制限があるためです。制限を超えると、後続のリクエストはブロックされます。ブロックとハング
  • Wait

概要#(1) Angular が Zone .js を使用して変更検出を実装する方法を簡単に説明します##(2) Angular の変更検出を理解した上で、原理をさらに明確にしますAngular のパフォーマンス最適化の概要と、ページのパフォーマンスが良好かどうかを判断する基準

(3) ターゲットを絞ったランタイム パフォーマンス最適化ソリューションを提供します

##プログラミング関連の知識の詳細については、次のサイトをご覧ください:

プログラミング入門

! !

以上がAngular はどのように最適化しますか?パフォーマンス最適化ソリューションの簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Goフレームワークのパフォーマンス最適化と水平拡張技術? Goフレームワークのパフォーマンス最適化と水平拡張技術? Jun 03, 2024 pm 07:27 PM

Go アプリケーションのパフォーマンスを向上させるために、次の最適化手段を講じることができます。 キャッシュ: キャッシュを使用して、基盤となるストレージへのアクセス数を減らし、パフォーマンスを向上させます。同時実行性: ゴルーチンとチャネルを使用して、長いタスクを並行して実行します。メモリ管理: メモリを手動で管理し (安全でないパッケージを使用)、パフォーマンスをさらに最適化します。アプリケーションをスケールアウトするには、次の手法を実装できます。 水平スケーリング (水平スケーリング): アプリケーション インスタンスを複数のサーバーまたはノードにデプロイします。負荷分散: ロード バランサーを使用して、リクエストを複数のアプリケーション インスタンスに分散します。データ シャーディング: 大規模なデータ セットを複数のデータベースまたはストレージ ノードに分散して、クエリのパフォーマンスとスケーラビリティを向上させます。

C++ パフォーマンス最適化ガイド: コードをより効率的にする秘訣を発見します。 C++ パフォーマンス最適化ガイド: コードをより効率的にする秘訣を発見します。 Jun 01, 2024 pm 05:13 PM

C++ のパフォーマンスの最適化には、1. 動的割り当ての回避、2. コンパイラ最適化フラグの使用、4. アプリケーションのキャッシュ、5. 並列プログラミングなどのさまざまな手法が含まれます。最適化の実際のケースでは、整数配列内の最長の昇順サブシーケンスを見つけるときにこれらの手法を適用して、アルゴリズムの効率を O(n^2) から O(nlogn) に改善する方法を示します。

C++ を使用したロケット エンジンのパフォーマンスの最適化 C++ を使用したロケット エンジンのパフォーマンスの最適化 Jun 01, 2024 pm 04:14 PM

C++ は、数学的モデルを構築し、シミュレーションを実行し、パラメーターを最適化することにより、ロケット エンジンのパフォーマンスを大幅に向上させることができます。ロケット エンジンの数学的モデルを構築し、その動作を記述します。エンジンのパフォーマンスをシミュレートし、推力や比推力などの主要なパラメーターを計算します。主要なパラメータを特定し、遺伝的アルゴリズムなどの最適化アルゴリズムを使用して最適な値を検索します。エンジンのパフォーマンスは最適化されたパラメータに基づいて再計算され、全体的な効率が向上します。

最適化への道: Java フレームワークのパフォーマンス向上への道のりを探る 最適化への道: Java フレームワークのパフォーマンス向上への道のりを探る Jun 01, 2024 pm 07:07 PM

Java フレームワークのパフォーマンスは、キャッシュ メカニズム、並列処理、データベースの最適化を実装し、メモリ消費を削減することによって向上できます。キャッシュ メカニズム: データベースまたは API リクエストの数を減らし、パフォーマンスを向上させます。並列処理: マルチコア CPU を利用してタスクを同時に実行し、スループットを向上させます。データベースの最適化: クエリの最適化、インデックスの使用、接続プールの構成、およびデータベースのパフォーマンスの向上。メモリ消費量を削減する: 軽量フレームワークを使用し、リークを回避し、分析ツールを使用してメモリ消費量を削減します。

nginxパフォーマンスチューニング:速度と低レイテンシの最適化 nginxパフォーマンスチューニング:速度と低レイテンシの最適化 Apr 05, 2025 am 12:08 AM

NGINXのパフォーマンスチューニングは、ワーカープロセスの数、接続プールサイズの数、GZIP圧縮とHTTP/2プロトコルの有効化、およびキャッシュとロードバランスを使用することで実現できます。 1.ワーカープロセスの数と接続プールサイズを調整します:worker_processesauto;イベント{worker_connections1024;}。 2。GZIP圧縮とhttp/2プロトコルを有効にします:http {gzipon; server {risten43sslhttp2;}}。 3。キャッシュ最適化:http {proxy_cache_path/path/to/cachelevels = 1:2k

Java でプロファイリングを使用してパフォーマンスを最適化するにはどうすればよいですか? Java でプロファイリングを使用してパフォーマンスを最適化するにはどうすればよいですか? Jun 01, 2024 pm 02:08 PM

Java でのプロファイリングは、アプリケーション実行の時間とリソース消費を決定するために使用されます。 JavaVisualVM を使用してプロファイリングを実装する: JVM に接続してプロファイリングを有効にし、サンプリング間隔を設定し、アプリケーションを実行してプロファイリングを停止すると、分析結果に実行時間のツリー ビューが表示されます。パフォーマンスを最適化する方法には、ホットスポット削減方法の特定と最適化アルゴリズムの呼び出しが含まれます。

プログラムのパフォーマンスを最適化するための一般的な方法は何ですか? プログラムのパフォーマンスを最適化するための一般的な方法は何ですか? May 09, 2024 am 09:57 AM

プログラムのパフォーマンスの最適化方法には、次のようなものがあります。 アルゴリズムの最適化: 時間の複雑さが低いアルゴリズムを選択し、ループと条件文を減らします。データ構造の選択: ルックアップ ツリーやハッシュ テーブルなどのデータ アクセス パターンに基づいて、適切なデータ構造を選択します。メモリの最適化: 不要なオブジェクトの作成を回避し、使用されなくなったメモリを解放し、メモリ プール テクノロジを使用します。スレッドの最適化: 並列化できるタスクを特定し、スレッド同期メカニズムを最適化します。データベースの最適化: インデックスを作成してデータの取得を高速化し、クエリ ステートメントを最適化し、キャッシュまたは NoSQL データベースを使用してパフォーマンスを向上させます。

PHP のパフォーマンスの問題を迅速に診断する方法 PHP のパフォーマンスの問題を迅速に診断する方法 Jun 03, 2024 am 10:56 AM

PHP のパフォーマンスの問題を迅速に診断するための効果的な手法には、Xdebug を使用してパフォーマンス データを取得し、Cachegrind の出力を分析することが含まれます。 Blackfire を使用してリクエスト トレースを表示し、パフォーマンス レポートを生成します。データベース クエリを調べて、非効率なクエリを特定します。メモリ使用量を分析し、メモリ割り当てとピーク使用量を表示します。

See all articles