Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

青灯夜游
青灯夜游nach vorne
2022-05-11 10:35:362592Durchsuche

Was ist Änderungserkennung? Im folgenden Artikel lernen Sie den Änderungserkennungsmechanismus in Angular kennen, sprechen über die Funktionsweise der Änderungserkennung und stellen die Leistungsoptimierungsmethode der Angular-Änderungserkennung vor. Ich hoffe, dass er für alle hilfreich ist!

Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

Was ist Änderungserkennung?

Das Konzept der Änderungserkennung

Nachdem sich der Datenstatus in der Komponente geändert hat, muss die Ansicht entsprechend aktualisiert werden. Dieser Mechanismus zum Synchronisieren von Ansichten und Daten wird als Änderungserkennung bezeichnet. [Verwandte Tutorial-Empfehlung: „Angular Tutorial“]

Trigger-Timing der Änderungserkennung

Solange ein asynchroner Vorgang (Ereignisse, Timer, XHR) stattfindet, geht Angular davon aus, dass sich der Status möglicherweise geändert hat, und dann Es wird eine Änderungserkennung durchgeführt.

  • Ereignisse: Klick, Mouseover, Mouseout, Keyup, Keydown und andere Browserereignisse;
  • XHR: Verschiedene Anfragen usw.
  • Da die Änderungserkennung bei asynchronen Vorgängen durchgeführt wird, wie abonniert Angular asynchrone Anforderungen und führt die Änderungserkennung durch?
  • Hier stellen wir NgZone und sein Fork-Objekt Zone.js vor.

Zone.js wird zum Kapseln und Abfangen asynchroner Aktivitäten im Browser verwendet. Es bietet außerdem

asynchrone Lebenszyklus-Hooks

und NgZone以及它的fork对象Zone.js

Zone.js 用于封装和拦截浏览器中的异步活动、它还提供 异步生命周期的钩子 和 统一的异步错误处理机制。

Zone.js 是通过 Monkey Patching(猴子补丁) 的方式来对浏览器中的常见方法和元素进行拦截,例如 setTimeout 和 HTMLElement.prototype.onclick。Angular 在启动时会利用 Zone.js 修补几个低级浏览器 API,从而实现异步事件的捕获,并在捕获时间后调用变更检测。

Angular通过forkZone.js并拓展出一个自己的区域NgZone,让应用中的所有异步操作都会运行在这个区域中。

Angular的变更检测如何工作的?

Angualr会为每一个组件生成一个变化监测器changeDetector ,记录组件的变化状态。

我们在创建了一个Angular 应用后,Angular 会同时创建一个 ApplicationRef  的实例,这个实例代表的就是我们当前创建的这个 Angular 应用的实例。 ApplicationRef 创建的同时,会订阅 ngZone 中的 onMicrotaskEmpty  事件,在所有的微任务完成后调用所有的视图的detectChanges()来执行变更检测。

变更检测的执行顺序

  • 更新所有子子组件绑定的属性

  • 调用所有子组件生命周期的钩子 OnChanges, OnInit, DoCheck,AfterContentInit

  • 更新当前组件的DOM

  • 调用子组件的变更检测

  • 调用所有子组件的生命周期钩子 ngAfterViewInit

举个栗子,我们在开发模式的时候可能会遇到这种报错:

Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

这是由于变更检测遵循从根组件开始,从上到下,执行每个组件的变更检测,直到最后一个组件达到稳定状态。而在下一次变更检测之前,子孙组件都不允许去修改父组件里的属性。

情况1 在开发模式下,Angular会进行二次检测 (生产环境下调用enableProdMode()einheitlichen asynchronen Fehlerbehandlungsmechanismus.

Zone.js verwendet

Monkey Patching, um gängige Methoden und Elemente in Browsern abzufangen, wie z. B. setTimeout und HTMLElement.prototype.onclick . Angular nutzt Zone.js, um beim Start mehrere Low-Level-Browser-APIs zu patchen, um asynchrone Ereignisse zu erfassen und die Änderungserkennung nach der Erfassungszeit aufzurufen. Angular forkt Zone.js auf und erweitert seine eigene Zone NgZone, sodass alle asynchronen Vorgänge in der Anwendung in dieser Zone ausgeführt werden.

Wie funktioniert die Änderungserkennung von Angular?

Angualr generiert für jede Komponente einen Änderungsdetektor changeDetector, um den Änderungsstatus der Komponente aufzuzeichnen.

对于Angular的变更检测如何优化?

由于组件默认执行 Default策略 ,任何异步操作都会触发整个组件数从上到下的检查。即使Angular团队不断提升性能,可以在毫秒内完成上百次检测,但是当应用拓展至百上千个组件组成时,庞大的组件树对应的变更检测也会达到性能瓶颈。

此时,我们就需要开始分析并减少不必要的检测次数。

如何减少检测次数

  • 区域污染(Zone Pollution)

    一般我们在生命周期钩子里使用第三方库,比如chart类库初始化,会自带requestAnimationRequest/setTimeout/addEventListener,我们可以将初始化方法写入NgZonerunOutsideAngular方法中。

Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

  • OnPush 策略

    对于不涉及更新操作的视图可以剥离出组件,使用onPush策略,以通知更新的方式刷新视图(见上方 变更检测的执行策略 部分)。

Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?

  • pure pipe 代替 {{function(data)}}

    在html文件内,{{function(data)}}

      Der Eingabewert (@Input) ändert sich

      (der in die Eingabe eingegebene Wert muss ein neuer sein Referenz)

Eine der aktuellen Komponenten oder Unterkomponenten hat das Ereignis ausgelöstEine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden? (aber in der onPush-Strategie lösen die folgenden Vorgänge keine Änderungserkennung aus)

Das obige ist der detaillierte Inhalt vonEine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen