eckigWie optimiert man die Leistung? Der folgende Artikel gibt Ihnen eine ausführliche Einführung in die Leistungsoptimierungslösung von Angular – Änderungserkennung. Ich hoffe, er wird Ihnen hilfreich sein!
Angular能 Leistungsoptimierung – Änderungserkennung
Die Grundursache ist: JavaScript-Ausführung und Seitendarstellung im Browser blockieren sich gegenseitig
.
Durch Beobachtung des FPS-Panels können wir die Sprachkompetenz der aktuellen Seite leicht überwachen
根因在于:浏览器中的 JavaScript 执行和页面渲染会相互阻塞
。
在 Chrome 的 devtools 中我们可以执行 Cmd+Shift+P 输入 show fps 来快速打开 fps 面板,如下图所示:
通过观察 FPS 面板,我们可以很方便的对当前页面的流畅度进行监控
1 影响页面性能的因素
页面交互是否流畅,在于页面响应是否流畅,而页面响应其本质上就是把页面状态的变更重新渲染到页面上的过程。
页面响应过程大致如下:
一般情况Event Handler事件处理逻辑不会消耗太多时间,所以影响angular性能的因素主要在于异步事件触发
和变更检测
1 Impact Page Performance-Faktoren 交Ob die Seiteninteraktion reibungslos verläuft, hängt davon ab, ob die Seitenreaktion reibungslos verläuft, und die
Seitenreaktionbesteht im Wesentlichen darin, die Änderung des Seitenstatus auf der Seite neu darzustellen.
Der Seitenantwortprozess ist ungefähr wie folgt:
Im Allgemeinen nimmt die Ereignisverarbeitungslogik des Event-Handlers nicht zu viel Zeit in Anspruch, sodass die Faktoren, die sich auf die Winkelleistung auswirken, hauptsächlich in der asynchronen Ereignisauslösung
und der Änderungserkennung liegen
.
Im Allgemeinen nimmt die Ereignisverarbeitungslogik des Event-Handlers nicht zu viel Zeit in Anspruch, sodass die Faktoren, die sich auf die Angular-Leistung auswirken, hauptsächlich in der asynchronen Ereignisauslösung und der Änderungserkennung liegen.
Für Angular ist der Prozess des Seitenrenderings der Prozess der Änderungserkennung. Es versteht sich, dass die Änderungserkennung von Angular innerhalb von 16,6 ms abgeschlossen sein muss, um Seitenrahmenverluste und Verzögerungen zu vermeiden. Sie können die Leistung der Seitenantwort unter den folgenden drei Aspekten optimieren. (1) Für die Triggerereignisphase können Sie
das Auslösen asynchroner Ereignisse reduzieren, um die Gesamtzahl der Änderungserkennungen und des erneuten Renderns zu reduzieren;
(2) Für die Ausführungslogikstufe des Ereignishandlers kann die Ausführungszeit durch Optimierung der komplexen Codelogik reduziert werden. (3) Für die Datenbindung und Aktualisierung der DOM-Stufe der Änderungserkennung und Vorlagendaten kann reduziert werden Die Anzahl der Berechnungen um die Rendering-Zeit zu reduzieren;
Für (2) Event-Handler müssen spezifische Probleme im Detail analysiert werden, hauptsächlich für (1) (3)2
Optimierung Plan
2.1 Reduzieren Sie die Auslösung asynchroner Ereignisse
Im standardmäßigen Änderungserkennungsmodus lösen asynchrone Ereignisse die globale Änderungserkennung aus Asynchrone Ereignisse werden die Leistung von Angular erheblich verbessern. Zu den asynchronen Ereignissen gehören der Vorfall „Makroaufgabe“ (Makromission) und das Mikroaufgabeereignis „Mikroaufgabe“
Die Optimierung asynchroner Ereignisse dient hauptsächlich der Überwachung von Dokumentereignissen. Zum Beispiel Click, Mouseup, Mousemove ... und andere Listening-Ereignisse im Dokument. : Überwachungsereignisszenario: 事 Renderer2.Listen (Dokument, ...) Fromevent (Dokument, ...) Document.adDeventristener (…) 🎜🎜 Das DOM-Überwachungsereignis muss entfernt werden, wenn es nicht ausgelöst werden muss . 🎜Beispiel: Eingabeaufforderungsfeldbefehl [pop]
Verwendungsszenarien: Tabellenspaltenfilterung, Klicken auf eine andere Stelle als das Symbol oder Seitenscrollen, Spaltenfilterung, Ausblenden des Popup-Felds
Der vorherige Ansatz bestand darin, das Klickereignis des Dokuments direkt zu überwachen und Scroll-Ereignis, dies hat den Nachteil, dass das Eingabeaufforderungsfeld nicht angezeigt wird, es aber immer noch ein Abhörereignis gibt, was sehr unzumutbar ist.案 Angemessene Lösung: Wenn die Eingabeaufforderung angezeigt wird, überwachen Sie die Click- und Scroll-Ereignisse und entfernen Sie den Überwachungsvorfall, wenn er ausgeblendet ist.
Für häufig ausgelöste DOM-Listening-Ereignisse können Sie RJX-Operatoren verwenden, um Ereignisse zu optimieren. Weitere Informationen finden Sie unter
Rjx-Operator. RxJS Marbles.
2.2 ÄnderungserkennungWas ist Änderungserkennung?
Um die Änderungserkennung zu verstehen, können wir die Antwort aus dem Ziel der Änderungserkennung finden. Das Ziel der Winkeländerungserkennung besteht darin, das Modell (TypeScript-Code) und die Vorlage (HTML) synchron zu halten. Daher kann die Änderungserkennung wie folgt verstanden werden:
Während Sie Modelländerungen erkennen, aktualisieren Sie die Vorlage (DOM ) . Was ist der Änderungserkennungsprozess?
kann erkannt werden, indem die Änderungserkennung in der Reihenfolge
von oben nach unten durchgeführt wird, das heißt, die Änderungserkennung wird zuerst an der übergeordneten Komponente und dann an der untergeordneten Komponente durchgeführt. Überprüfen Sie zunächst die Datenänderungen der übergeordneten Komponente und aktualisieren Sie dann die Vorlage der übergeordneten Komponente. Wenn Sie beim Aktualisieren der Vorlage auf eine untergeordnete Komponente stoßen, wird der an die untergeordnete Komponente gebundene Wert aktualisiert und dann die untergeordnete Komponente eingegeben, um festzustellen, ob die Vorlage vorhanden ist Wenn sich der Index des @Input-Eingabewerts geändert hat, markieren Sie die Unterkomponente als fehlerhaft, was eine anschließende Änderungserkennung erfordert. Aktualisieren Sie nach dem Markieren der Unterkomponente weiterhin die Vorlage hinter der Unterkomponente in der übergeordneten Komponente wurden aktualisiert, nehmen Sie Änderungen an der Unterkomponentenerkennung vor. 2.2.1 Prinzip der Angular-Änderungserkennung
Im Standardmodus der Änderungserkennung besteht das Prinzip der asynchronen Ereignisse, die die Änderungserkennung von Angular auslösen, darin, dass Angular die tick()-Methode von ApplicationRef aus der Stammkomponente aufruft und Zone.js zur Verarbeitung verwendet asynchrone Ereignisse. Führen Sie eine Änderungserkennung für Unterkomponenten durch. Während des Initialisierungsprozesses der Angular-Anwendung wird eine Zone (NgZone) instanziiert und dann wird die gesamte Logik im _inner-Objekt des Objekts ausgeführt.
Zone.js implementiert die folgenden Klassen:
Zone-Klasse, die Ausführungsumgebung von JavaScript-Ereignissen, können wie Threads einige Daten übertragen und über übergeordnete und untergeordnete Zonen verfügen.Benutzeroperationen lösen asynchrone Ereignisse aus (z. B. DOM-Ereignisse, Schnittstellenanforderungen ...)
=> Die runTask()-Methode von Zone wird in der Funktion invokeTask() aufgerufen. In der runTask-Methode ruft Zone den Hook von ZoneSpec über das Instanzattribut _zoneDelegate auf.
=> Die drei Hooks von ZoneSpec (onInvokeTask, onInvoke, onHasTask) bestehen checkStable ()-Funktion löst die Zone.onMicrotaskEmpty.emit(null)-Benachrichtigung aus
=> Die Root-Komponente ruft tick() auf, nachdem sie onMicrotaskEmpty überwacht hat, und die tick-Methode ruft detectChanges()
auf, um die Erkennung zu starten Root-Komponente
= > ··· refreshView()
ruft executeTemplate()
auf, und die executeTemplate
-Methode ruft templateFn() auf
, um die Vorlage zu aktualisieren, den an die Unterkomponente gebundenen Wert (Zu diesem Zeitpunkt wird erkannt, ob sich die Eingabereferenz der Unterkomponente
@Input() geändert hat. Wenn ja Bei einer Änderung wird die Unterkomponente als
Dirty markiert, d. h. diese Unterkomponente erfordert eine Änderungserkennung
).
Vereinfachen Sie den Prozess:
Lösen Sie ein asynchrones Ereignis aus
=> ZoneDelegate ruft den Hook von ZoneSpec auf, um die onMicrotaskEmpty-Benachrichtigung auszulösen
=> Benachrichtigung und führt tick() aus, beginnt mit der Erkennung und Aktualisierung von dom
Wie aus dem obigen Code ersichtlich ist,
.当微任务为空的时候才会触发变更检测
Einfaches Flussdiagramm zum Prinzip der Änderungserkennung:
Angular-Quellcode-Analyse Zone.js-Referenz
Blog. 2.2.2 Lösung zur Optimierung der Änderungserkennung
1) Verwenden Sie den OnPush-Modus
Prinzip: Reduzieren Sie den Zeitaufwand für eine Änderungserkennung.
Der Unterschied zwischen dem OnPush-Modus und dem Standardmodus besteht darin, dass DOM-Abhörereignisse, Timer-Ereignisse und Versprechen keine Änderungserkennung auslösen. Der Komponentenstatus im Standardmodus ist immer CheckAlways, was bedeutet, dass die Komponente in jedem Erkennungszyklus getestet werden muss.
Im OnPush-Modus: Die folgenden Situationen lösen eine Änderungserkennung aus
S1, die @Input-Referenz der Komponente ändert sich.
S2. DOM-gebundene Ereignisse der Komponente, einschließlich DOM-gebundene Ereignisse ihrer Unterkomponenten, wie z. B. Klicken, Senden, Klicken mit der Maus. @HostListener()
Stellen Sie auch die Async-Pipe ein.
S4. Verwenden Sie die folgenden Methoden, um die Änderungserkennung manuell auszulösen:
ChangeDetectorRef.detectChanges(): Änderungserkennung der aktuellen Komponente und Nicht-OnPush-Unterkomponenten auslösen.
ChangeDetectorRef.markForCheck(): Markieren Sie die aktuelle Ansicht und alle ihre Vorgänger als schmutzig, und die Erkennung wird im nächsten Erkennungszyklus ausgelöst.
ApplicationRef.tick(): Löst keine Änderungserkennung aus
2) Verwenden Sie NgZone.runOutsideAngular()
Prinzip: Reduzieren Sie die Anzahl der Änderungserkennungen
Schreiben Sie eine globale Dom-Ereignisüberwachung in den Rückruf von NgZone.runOutsideAngular() -Methode. DOM-Ereignisse lösen die Änderungserkennung von Angular nicht aus. Wenn die aktuelle Komponente nicht aktualisiert wurde, können Sie den Hook „DetectChanges()“ von ChangeDetectorRef in der Rückruffunktion ausführen, um die Änderungserkennung der aktuellen Komponente manuell auszulösen.
Beispiel: dynamische Symbolkomponente app-icon-react
2.2.3 Debugging-Methode Methode 1: Sie können das Angular DevTools-Plugin in der Browserkonsole verwenden, um ein bestimmtes DOM-Ereignis anzuzeigen Erkennungsstatus:Methode 2: Sie können Folgendes direkt in die Konsole eingeben: ng.profiler.timeChangeDetection(), um die Erkennungszeit anzuzeigen. Diese Methode kann die globale Erkennungszeit anzeigen. Referenzblog
Profiling Angular Change Detection
2.3 Template (HTML)-Optimierung
2.3.1 DOM-Rendering reduzieren: ngFor plus trackByMit dem trackBy-Attribut von *ngFor ändert Angular nur Änderungen und rendert neu die geänderten Einträge, ohne dass die gesamte Liste der Einträge neu geladen werden muss.
Zum Beispiel: Tabellensortierungsszenario. Wenn trackBy zu ngFor hinzugefügt wird, werden beim Rendern der Tabelle nur die Zeilen-Dom-Elemente verschoben. Wenn trackBy nicht hinzugefügt wird, werden zuerst die vorhandenen Tabellen-Dom-Elemente gelöscht und dann die Zeilen-Dom-Elemente hinzugefügt. Offensichtlich ist die Leistung beim Verschieben nur von Dom-Elementen viel besser.板2.3.2 Verwenden Sie keine Funktionen im Vorlagenausdruck. Verwenden Sie nicht den Funktionsaufruf im Angular-Vorlagenausdruck. Sie können stattdessen auch die Pipe PIPE verwenden, um sie manuell zu ersetzen. Wenn Funktionen in Vorlagen verwendet werden, wird die Funktion unabhängig davon, ob sich der Wert geändert hat oder nicht, jedes Mal ausgeführt, wenn eine Änderungserkennung durchgeführt wird, was sich auf die Leistung auswirkt.
Szenarien für die Verwendung von Funktionen in Vorlagen:
2.3.3 Reduzieren Sie die Verwendung von ngFor
Die Verwendung von ngFor beeinträchtigt die Leistung, wenn die Datenmenge groß ist.
Beispiel:
Verwenden Sie ngFor:
Nicht die Verwendung von ngFor: Die Leistung wird um etwa das Zehnfache verbessert
Weitere Programmierkenntnisse finden Sie unter: Programmiervideo ! !
Das obige ist der detaillierte Inhalt vonWie kann die Leistung in Angular optimiert werden? Eine kurze Analyse der Methoden zur Änderungserkennung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!