


Eine kurze Analyse des Änderungserkennungsmechanismus von Angular und wie kann die Leistung optimiert werden?
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!
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
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
举个栗子,我们在开发模式的时候可能会遇到这种报错:
这是由于变更检测遵循从根组件开始,从上到下,执行每个组件的变更检测,直到最后一个组件达到稳定状态。而在下一次变更检测之前,子孙组件都不允许去修改父组件里的属性。
情况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.
Nachdem wir eine Angular-Anwendung erstellt haben, erstellt Angular auch eine Instanz von ApplicationRef
. Diese Instanz stellt die Instanz der Angular-Anwendung dar, die wir gerade erstellen. Wenn ApplicationRef
erstellt wird, wird onMicrotaskEmpty- Ereignis: Nachdem alle Mikrotasks abgeschlossen sind, rufen Sie
detectChanges()
aller Ansichten auf, um eine Änderungserkennung durchzuführen.
Ausführungsreihenfolge der Änderungserkennung
Aktualisieren Sie die an alle untergeordneten Unterkomponenten gebundenen Eigenschaften 🎜 🎜Rufen Sie die Lebenszyklus-Hooks OnChanges, OnInit, DoCheck, AfterContentInit aller Unterkomponenten auf.🎜🎜🎜🎜Aktualisieren Sie das DOM der aktuellen Komponente.🎜🎜🎜🎜Rufen Sie die Änderungserkennung der Unterkomponente auf alle Unterkomponenten🎜🎜 🎜🎜Zum Beispiel kann dieser Fehler auftreten, wenn wir uns im Entwicklungsmodus befinden: 🎜🎜
🎜🎜Dies liegt daran, dass die Änderungserkennung ausgehend von der Stammkomponente von oben nach unten erfolgt und die Änderungserkennung für jede Komponente durchgeführt wird, bis die letzte Komponente a erreicht stabiler Zustand. Vor der nächsten Änderungserkennung dürfen untergeordnete Komponenten die Eigenschaften in der übergeordneten Komponente nicht ändern. 🎜🎜🎜🎜Fall 1🎜🎜 Im Entwicklungsmodus führt Angular eine 🎜sekundäre Erkennung🎜 durch (beim Aufruf von enableProdMode()
in der Produktionsumgebung wird die Anzahl der Erkennungen auf 1 reduziert). Sobald wir nach Abschluss von 🎜Schritt 4🎜 die Eigenschaften der übergeordneten Komponente in der untergeordneten Komponente ändern und Angular die zweite Erkennung durchführt und feststellt, dass die beiden Werte inkonsistent sind, tritt der obige Fehler auf. 🎜🎜🎜🎜Fall 2🎜🎜 Solange die übergeordnete Komponente Eigenschaften an die untergeordnete Komponente bindet, tritt ein Fehler auf, unabhängig davon, ob der folgende Code in einem der Lebenszyklus-Hooks zwischen OnChanges, OnInit, DoCheck, AfterContentInit und AfterViewInit ausgeführt wird gemeldet werden. 🎜// #parent
{{data}}
<child [data]="data"></child>
// in child component ts, execute:
this.parent.data = 'new Value';
Nach dem Login kopieren🎜🎜Ausführungsstrategie zur Änderungserkennung🎜🎜🎜🎜🎜🎜🎜🎜Standardstrategie🎜🎜🎜🎜
Jedes Mal, wenn ein Ereignis eine Änderungserkennung auslöst (z. B. Benutzerereignisse, Timer, XHR, Versprechen usw.), überprüft diese Standardstrategie jede Komponente im Komponentenbaum von oben nach unten. Diese konservative Prüfmethode, die keine Annahmen über Komponentenabhängigkeiten trifft, wird als „Dirty Checking“ bezeichnet. Diese Strategie wirkt sich auf die Leistung unserer Anwendung aus, wenn wir zu viele Komponenten verwenden.
OnPush-StrategieÄndern Sie die changeDetection
des Komponentendekorators. Nachdem Sie ihn auf die OnPush-Strategie eingestellt haben, überspringt Angular die Komponente und ändert sich jedes Mal Die Änderungserkennung aller Unterkomponenten der Komponente wird ausgelöst.
Unter der OnPush
-Strategie lösen nur die folgenden Situationen eine Komponentenänderungserkennung aus: changeDetection
,设置为 OnPush 策略后,Angular 每次触发变化检测后会跳过该组件和该组件的所以子组件变化检测。
在 OnPush
策略下,只有以下这几种情况才会触发组件的变化检测:
- 输入值(@Input)更改(入input的值必须是一个新的引用)
- 当前组件或子组件之一触发了事件 (但在onPush策略中,以下操作不会触发变更检测)
- setTimeout()
- setInterval()
- Promise.resolve().then()
- this.http.get('...').subscribe()
- 手动触发变更检测(每个组件都会关联一个组件视图ChangeDetectorRef)
- detectChanges(): 它会触发当前组件和子组件的变化检测
- markForCheck(): 它不会触发变化检测,但是会把当前的OnPush组件和所以的父组件为OnPush的组件 标记为需要检测状态 ,在当前或者下一个变化检测周期进行检测
- ApplicationRef.tick() : 它会根据组件的变化检测策略,触发整个应用程序的更改检测

- async pipe
对于Angular的变更检测如何优化?
changeDetector
, um den Änderungsstatus der Komponente aufzuzeichnen. ApplicationRef
. Diese Instanz stellt die Instanz der Angular-Anwendung dar, die wir gerade erstellen. Wenn ApplicationRef
erstellt wird, wird onMicrotaskEmptydetectChanges()
aller Ansichten auf, um eine Änderungserkennung durchzuführen.
Ausführungsreihenfolge der Änderungserkennung
Aktualisieren Sie die an alle untergeordneten Unterkomponenten gebundenen Eigenschaften 🎜 🎜Rufen Sie die Lebenszyklus-Hooks OnChanges, OnInit, DoCheck, AfterContentInit aller Unterkomponenten auf.🎜🎜🎜🎜Aktualisieren Sie das DOM der aktuellen Komponente.🎜🎜🎜🎜Rufen Sie die Änderungserkennung der Unterkomponente auf alle Unterkomponenten🎜🎜 🎜🎜Zum Beispiel kann dieser Fehler auftreten, wenn wir uns im Entwicklungsmodus befinden: 🎜🎜
🎜🎜Dies liegt daran, dass die Änderungserkennung ausgehend von der Stammkomponente von oben nach unten erfolgt und die Änderungserkennung für jede Komponente durchgeführt wird, bis die letzte Komponente a erreicht stabiler Zustand. Vor der nächsten Änderungserkennung dürfen untergeordnete Komponenten die Eigenschaften in der übergeordneten Komponente nicht ändern. 🎜🎜🎜🎜Fall 1🎜🎜 Im Entwicklungsmodus führt Angular eine 🎜sekundäre Erkennung🎜 durch (beim Aufruf von enableProdMode()
in der Produktionsumgebung wird die Anzahl der Erkennungen auf 1 reduziert). Sobald wir nach Abschluss von 🎜Schritt 4🎜 die Eigenschaften der übergeordneten Komponente in der untergeordneten Komponente ändern und Angular die zweite Erkennung durchführt und feststellt, dass die beiden Werte inkonsistent sind, tritt der obige Fehler auf. 🎜🎜🎜🎜Fall 2🎜🎜 Solange die übergeordnete Komponente Eigenschaften an die untergeordnete Komponente bindet, tritt ein Fehler auf, unabhängig davon, ob der folgende Code in einem der Lebenszyklus-Hooks zwischen OnChanges, OnInit, DoCheck, AfterContentInit und AfterViewInit ausgeführt wird gemeldet werden. 🎜// #parent
{{data}}
<child [data]="data"></child>
// in child component ts, execute:
this.parent.data = 'new Value';
Nach dem Login kopieren🎜🎜Ausführungsstrategie zur Änderungserkennung🎜🎜🎜🎜🎜🎜🎜🎜Standardstrategie🎜🎜🎜🎜
// #parent {{data}} <child [data]="data"></child> // in child component ts, execute: this.parent.data = 'new Value';
Jedes Mal, wenn ein Ereignis eine Änderungserkennung auslöst (z. B. Benutzerereignisse, Timer, XHR, Versprechen usw.), überprüft diese Standardstrategie jede Komponente im Komponentenbaum von oben nach unten. Diese konservative Prüfmethode, die keine Annahmen über Komponentenabhängigkeiten trifft, wird als „Dirty Checking“ bezeichnet. Diese Strategie wirkt sich auf die Leistung unserer Anwendung aus, wenn wir zu viele Komponenten verwenden.
OnPush-StrategieÄndern Sie die changeDetection
des Komponentendekorators. Nachdem Sie ihn auf die OnPush-Strategie eingestellt haben, überspringt Angular die Komponente und ändert sich jedes Mal Die Änderungserkennung aller Unterkomponenten der Komponente wird ausgelöst.
Unter der OnPush
-Strategie lösen nur die folgenden Situationen eine Komponentenänderungserkennung aus: changeDetection
,设置为 OnPush 策略后,Angular 每次触发变化检测后会跳过该组件和该组件的所以子组件变化检测。
在 OnPush
策略下,只有以下这几种情况才会触发组件的变化检测:
- 输入值(@Input)更改(入input的值必须是一个新的引用)
- 当前组件或子组件之一触发了事件 (但在onPush策略中,以下操作不会触发变更检测)
- setTimeout()
- setInterval()
- Promise.resolve().then()
- this.http.get('...').subscribe()
- 手动触发变更检测(每个组件都会关联一个组件视图ChangeDetectorRef)
- detectChanges(): 它会触发当前组件和子组件的变化检测
- markForCheck(): 它不会触发变化检测,但是会把当前的OnPush组件和所以的父组件为OnPush的组件 标记为需要检测状态 ,在当前或者下一个变化检测周期进行检测
- ApplicationRef.tick() : 它会根据组件的变化检测策略,触发整个应用程序的更改检测
- async pipe
由于组件默认执行 Default策略 ,任何异步操作都会触发整个组件数从上到下的检查。即使Angular团队不断提升性能,可以在毫秒内完成上百次检测,但是当应用拓展至百上千个组件组成时,庞大的组件树对应的变更检测也会达到性能瓶颈。
此时,我们就需要开始分析并减少不必要的检测次数。
如何减少检测次数
区域污染(Zone Pollution)
一般我们在生命周期钩子里使用第三方库,比如chart类库初始化,会自带requestAnimationRequest/setTimeout/addEventListener,我们可以将初始化方法写入
NgZone
的runOutsideAngular
方法中。
OnPush 策略
对于不涉及更新操作的视图可以剥离出组件,使用onPush策略,以通知更新的方式刷新视图(见上方 变更检测的执行策略 部分)。
用 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öst (aber in der onPush-Strategie lösen die folgenden Vorgänge keine Änderungserkennung aus)
setInterval()
🎜🎜🎜this.http.get('...').subscribe()🎜🎜🎜🎜🎜🎜Änderungserkennung manuell auslösen🎜(Jede Komponente wird einer Komponente zugeordnet ViewChangeDetectorRef)- 🎜🎜🎜detectChanges():🎜 Es löst die Änderungserkennung der aktuellen Komponente und Unterkomponenten aus. 🎜🎜🎜🎜🎜markForCheck(): 🎜 Es löst keine Änderungserkennung aus, aber es löst den aktuellen OnPush aus Komponente und so Die übergeordnete Komponente ist eine OnPush-Komponente 🎜, die als erkennungsbedürftig markiert ist 🎜 und wird im aktuellen oder nächsten Änderungserkennungszyklus erkannt 🎜🎜🎜🎜🎜ApplicationRef.tick()🎜 : Sie löst die gesamte Anwendung entsprechend aus Änderungserkennungsstrategie der Komponente Änderungserkennung🎜🎜🎜
🎜🎜🎜asynchrone Pipe🎜🎜🎜🎜🎜
🎜Wie optimiert man die Änderungserkennung von Angular? 🎜
🎜Da die Komponente standardmäßig die 🎜Standardstrategie🎜 ausführt, löst jeder asynchrone Vorgang eine Überprüfung der gesamten Komponentennummer von oben nach unten aus. Selbst wenn das Angular-Team die Leistung weiter verbessert und Hunderte von Erkennungen innerhalb von Millisekunden durchführen kann, kommt es bei der Erweiterung der Anwendung auf Hunderte oder Tausende von Komponenten zu einem Leistungsengpass bei der Änderungserkennung, die dem riesigen Komponentenbaum entspricht. 🎜🎜An diesem Punkt müssen wir mit der Analyse beginnen und die Anzahl unnötiger Tests reduzieren. 🎜🎜So reduzieren Sie die Anzahl der Erkennungen🎜
🎜🎜🎜🎜Zonenverschmutzung🎜🎜🎜Im Allgemeinen verwenden wir Bibliotheken von Drittanbietern in Lebenszyklus-Hooks, wie z. B. Diagrammen Die Initialisierung der Klassenbibliothek erfolgt mit requestAnimationRequest/setTimeout/addEventListener. Wir können die Initialisierungsmethode in dierunOutsideAngular
-Methode vonNgZone
schreiben. 🎜🎜🎜🎜🎜 🎜🎜🎜🎜OnPush-Strategie🎜🎜🎜Für Ansichten, die keine Aktualisierungsvorgänge beinhalten, können Sie Komponenten trennen und die onPush-Strategie verwenden, um die Ansicht durch Benachrichtigung über Aktualisierungen zu aktualisieren (siehe Abschnitt 🎜Ausführungsstrategie zur Änderungserkennung🎜 oben). 🎜🎜🎜🎜
🎜 🎜🎜🎜🎜Verwenden Sie reine Pipe🎜 anstelle von {{function(data)}}🎜🎜🎜In der HTML-Datei führt die Schreibmethode von
{{function(data)}}
dazu, dass alle Werte sind Bei jeder Änderungserkennung wird der Wert neu berechnet. (?: Wenn Sie eine Liste mit 1000 Elementen haben, ändern Sie nur eines der Daten, aber die anderen 999 Daten, die nicht aktualisiert werden müssen, werden ebenfalls neu berechnet.)🎜🎜Zu diesem Zeitpunkt können wir die Pipe-Methode verwenden , nur der geänderte Wert. Vorgänge werden ausgelöst, um einige Ansichten zu aktualisieren. 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜Angesichts der Darstellung großer Datenmengen wählen Sie virtuelles Scrollen/Paginierung, um Daten anzufordern🎜🎜🎜Die oben genannte 4-Punkte-Lösung stammt aus der Videoeinführung des 🎜Angular-Teams🎜 Video, Angular Devtool wird verwendet, um die Häufigkeit zu berechnen, um Probleme zu analysieren und zu lösen. Wenn Ihr Angular also 9+ ist, lesen Sie bitte weiter, um zu erfahren, wie Sie Angular Devtool installieren und ausführen. 🎜- Angular 9+, 支持Ivy。
- Guide和下载地址
- 保证运行环境为开发环境
// environment.dev.ts ... production: false ...
Nach dem Login kopieren - angular.json > dev配置项 >
"optimization": false
projects > your-project-name > architect > build > configurations > dev > "optimization": false
Nach dem Login kopieren
- setTimeout()
插件:Angular devtool使用介绍
更多编程相关知识,请访问:编程教学!!
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!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Angular.js ist eine frei zugängliche JavaScript-Plattform zum Erstellen dynamischer Anwendungen. Es ermöglicht Ihnen, verschiedene Aspekte Ihrer Anwendung schnell und klar auszudrücken, indem Sie die Syntax von HTML als Vorlagensprache erweitern. Angular.js bietet eine Reihe von Tools, die Sie beim Schreiben, Aktualisieren und Testen Ihres Codes unterstützen. Darüber hinaus bietet es viele Funktionen wie Routing und Formularverwaltung. In dieser Anleitung wird erläutert, wie Angular auf Ubuntu24 installiert wird. Zuerst müssen Sie Node.js installieren. Node.js ist eine JavaScript-Ausführungsumgebung, die auf der ChromeV8-Engine basiert und es Ihnen ermöglicht, JavaScript-Code auf der Serverseite auszuführen. In Ub sein

Dieser Artikel wird Sie dabei unterstützen, Angular weiter zu lernen und die eigenständige Komponente (Standalone Component) in Angular kurz zu verstehen. Ich hoffe, er wird Ihnen hilfreich sein!

Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des Angular-Statusmanagers NgRx und stellt Ihnen die Verwendung von NgRx vor. Ich hoffe, er wird Ihnen hilfreich sein!

Wie verwende ich den Monaco-Editor in Angular? Der folgende Artikel dokumentiert die Verwendung des Monaco-Editors in Angular, der kürzlich in einem Unternehmen verwendet wurde. Ich hoffe, dass er für alle hilfreich sein wird!

Kennen Sie Angular Universal? Es kann dazu beitragen, dass die Website eine bessere SEO-Unterstützung bietet!

In diesem Artikel erfahren Sie, wie Sie mit Angular in Kombination mit ng-zorro schnell ein Backend-System entwickeln. Ich hoffe, dass er für alle hilfreich ist.

Mit der rasanten Entwicklung des Internets wird auch die Front-End-Entwicklungstechnologie ständig verbessert und iteriert. PHP und Angular sind zwei Technologien, die in der Frontend-Entwicklung weit verbreitet sind. PHP ist eine serverseitige Skriptsprache, die Aufgaben wie die Verarbeitung von Formularen, die Generierung dynamischer Seiten und die Verwaltung von Zugriffsberechtigungen übernehmen kann. Angular ist ein JavaScript-Framework, mit dem Single-Page-Anwendungen entwickelt und komponentenbasierte Webanwendungen erstellt werden können. In diesem Artikel erfahren Sie, wie Sie PHP und Angular für die Frontend-Entwicklung verwenden und wie Sie diese kombinieren

Das Standardanzeigeverhalten für Komponenten im Angular-Framework gilt nicht für Elemente auf Blockebene. Diese Designwahl fördert die Kapselung von Komponentenstilen und ermutigt Entwickler, bewusst zu definieren, wie jede Komponente angezeigt wird. Durch explizites Festlegen der CSS-Eigenschaft display kann die Anzeige von Angular-Komponenten vollständig gesteuert werden, um das gewünschte Layout und die gewünschte Reaktionsfähigkeit zu erreichen.
