Wie messe ich die Leistung des Digest-Zyklus meiner AngularJS-App?


82

Was ist ein einfacher Weg, um die Dauer des Winkel-Verdauungszyklus zu messen? Es gibt verschiedene Methoden zur Analyse der Leistung des Verdauungszyklus, jedoch hat jede ihre eigenen Pitfals:

  • Chrome Profiler: Zu viele Details unterbrechen den Digest-Zyklus nicht auf leicht zu findende Weise
  • Batarang (AngularJS-Browser-Plugin): Zu viel Overhead, langsame Aktualisierungsrate, explodiert mit großen Apps.

... muss es einen besseren Weg geben ?! 1?

Antworten:


148

Hier ist ein Geheimnis. Führen Sie in den Chrome Dev Tools ein CPU-Profil aus. Nachdem Sie die Aufnahme beendet haben, befindet sich am unteren Bildschirmrand ein Dreieck nach unten neben "Schwer (von unten nach oben)". Klicken Sie auf das Dreieck und wählen Sie "Flame Chart". Sobald Sie sich im Flammendiagrammmodus befinden, können Sie zoomen und schwenken, um die Digest-Zyklen anzuzeigen, wie lange sie dauern und welche Funktionen genau aufgerufen werden. Das Flammendiagramm ist unglaublich nützlich, um Probleme beim Laden von Seiten, Probleme bei der Wiederholungsleistung und Probleme beim Digest-Zyklus aufzuspüren! Ich weiß wirklich nicht, wie ich vor dem Flame Chart debuggen und profilieren konnte. Hier ist ein Beispiel:

Flame Chart in Chrome Dev Tools


10
Vielen Dank. Ich habe es gerade versucht und es scheint sehr nützlich zu sein. Können Sie ein kurzes Demo-Video veröffentlichen, wie Sie es auf einer Website verwenden können, um ein Leistungsproblem zu erkennen und zu beheben? Es wäre sehr interessant. Danke noch einmal.
Soferio

3
Dies scheint nur "Diagramm" zu heißen und sieht in der aktuellen Version (Version 51.0) von Chrome etwas anders aus.
Marc Stober

Google hat ein detailliertes Tutorial mit kurzen Viudeos veröffentlicht: developer.google.com/web/tools/chrome-devtools/…
Vaiden

41

Die folgende Antwort zeigt Ihnen die Leerlaufleistung der $ Digest-Schleife, dh die Leistung des Digests, wenn sich keiner Ihrer Überwachungsausdrücke ändert. Dies ist hilfreich, wenn Ihre Anwendung auch dann träge erscheint, wenn sich die Ansicht nicht ändert. Für komplexere Situationen siehe die Antwort von aet.


Geben Sie Folgendes in die Konsole ein:

angular.element(document).injector().invoke(function($rootScope) { 
  var a = performance.now(); 
  $rootScope.$apply(); 
  console.log(performance.now()-a); 
})

Das Ergebnis gibt Ihnen die Dauer des Digest-Zyklus in Millisekunden an. Je kleiner die Zahl, desto besser.


HINWEIS:

Domi in den Kommentaren bemerkt: angular.element(document) wird nicht viel bringen, wenn Sie die ng-appDirektive für die Initialisierung verwendet haben. In diesem Fall holen Sie sich ng-appstattdessen das Element. ZB indem du es tustangular.element('#ng-app')

Sie können auch versuchen:

angular.element(document.querySelector('[ng-app]')).injector().invoke(function($rootScope) { 
  var a = performance.now(); 
  $rootScope.$apply(); 
  console.log(performance.now()-a); 
})

In diesem Fall ändert sich nichts, sodass keine Beobachter ausgeführt werden, nichts neu bewertet wird usw. Sie erhalten keine "echten" Zahlen.
Ein besserer Oliver

2
Natürlich sind es "reelle" Zahlen. Sie sind falsch, wenn Sie $ rootScope ausführen. $ Apply () bewertet alle Ihre Beobachter neu, um herauszufinden, ob sie sich geändert haben (andernfalls würde Angular wissen, dass sich nichts geändert hat?).
Gil Birman

Vielleicht meinen wir etwas anderes, also zitiere ich nur die Dokumente : The listener is called only when the value from the current watchExpression and the previous call to watchExpression are not equal. Ihr Code berücksichtigt keine Listener. Und eckig schafft viele Zuhörer. Sie würden niemals anrufen, $apply()wenn sich nichts geändert hat, daher erzählen Ihre Ergebnisse nur die Hälfte der Geschichte. Abhängig von den Umständen kann es das weniger interessante sein;)
ein besserer Oliver

1
Stellen Sie sich Folgendes vor: Sie haben 1000 Watch-Ausdrücke, alle werden ausgewertet, aber ein "Listener" wird als Ergebnis ausgelöst. Sind Sie mehr besorgt über die Leistung des Uhrausdrucks oder die Zuhörer?
Gil Birman

1
angular.element(document)wird nicht viel bringen, wenn Sie die ng-appDirektive für die Initialisierung verwendet haben. In diesem Fall holen Sie sich ng-appstattdessen das Element. ZB durch angular.element('#ng-app')...
Domi


14

Sie können auch die Winkelleistung verwenden

Diese Erweiterung bietet Echtzeit-Überwachungsdiagramme für die Anzahl der Beobachter, das Digest-Timing und die Digest-Rate. Sie erhalten auch die Digest-Timing-Verteilung, sodass Sie aus rekursiveren Paterns ein außergewöhnlich langes Digest-Timing erkennen können. Alle Echtzeitdaten sind mit Ereignissen verknüpft, sodass Sie bestimmen können, welche Aktionen die Anwendungsleistung verändert haben. Schließlich können Sie die Zeitdienstmethode zeitlich festlegen und deren Ausführung zählen, um diejenigen zu ermitteln, die den größeren Einfluss auf die Laufzeit Ihrer App haben.

Angular Performance Screenshot

Disclamer: Ich bin der Autor der Erweiterung


Ich habe es installiert, aber nicht herausgefunden, wie ich es verwenden soll. Hat Ihre Erweiterung dem Profiler von Chrome Funktionen hinzugefügt? Vielen Dank.
gm2008

Wenn Sie die Entwicklertools öffnen, sollten Sie eine Registerkarte "Winkel" mit dieser Ansicht haben.
Nicolas Joseph

Danke für die Antwort. Um die Erweiterung erfolgreich zu erstellen, muss ich auch Python, VCBuild.exe, Windows SDK installieren. Vielleicht könnten Sie Ihr Handbuch ergänzen.
gm2008

Ich bin unter Mac OsX, daher habe ich keine Ahnung, was für Windows benötigt wird. Vielleicht könnten Sie im Repo eine Pull-Anfrage stellen, um zu beschreiben, was Sie getan haben. Danke für die Information !
Nicolas Joseph

Was macht "Function Timing"? Ich habe einige Modulnamen eingegeben, aber es scheint nichts zu passieren.
Raoel

5

Ein praktisches Tool, um den Verdauungszyklus im Auge zu behalten, ist das hervorragende ng-stats-Tool von @kentcdodds . Es erzeugt so ein kleines visuelles Element und kann sogar über ein Lesezeichen implementiert werden. Es kann sogar in iFrames wie jsfiddle verwendet werden.

guter Verdauungszyklus Geben Sie hier die Bildbeschreibung ein

Wenig nützlich, um Statistiken über den eckigen Auszug / die Uhren Ihrer Seite anzuzeigen. Diese Bibliothek verfügt derzeit über ein einfaches Skript zum Erstellen eines Diagramms (siehe unten). Außerdem wird ein Modul namens angularStatsmit einer Direktive namens aufgerufen, mit angular-stats der Winkelstatistiken an einer bestimmten Stelle auf der von Ihnen angegebenen Seite platziert werden können.

Gefunden unter https://github.com/kentcdodds/ng-stats


2

Sie können UX Profiler verwenden

  • Benutzertransaktionsansicht, dh KLICKEN und alle dadurch verursachten Aktivitäten (andere Ereignisse, XHRs, Zeitüberschreitungen), gruppiert.
  • Zeitmessungen (wie es der Benutzer empfindet) der gesamten Benutzertransaktion und / oder ihrer Teile.
  • Kombinierte asynchrone Stapelverfolgung.
  • Fokussierter Profiler - Profil nur das problematische Ereignis.
  • Angular 1.x Integration.

Geben Sie hier die Bildbeschreibung ein


1

Für den strengen Modus, einen Lauf von Digest Cucle, führen Sie ihn in der F12-Konsole in Chrome aus

angular.element(document).injector().invoke(['$rootScope',function($rootScope) { var a = performance.now(); $rootScope.$apply(); return performance.now()-a; }])

0

Die oben beschriebenen Tools haben Sie bereits auf die Idee gebracht, die Leistung der Digest-Schleife zu messen. Die meisten wichtigen Punkte zur Steigerung der Performance des Digest-Zyklus sind

  • Überwachen Sie Scroll-Ereignisse genau, um alle unsichtbaren Elemente auszublenden und
    die Anzahl der Beobachter erheblich zu verringern.

  • Verwalten Sie überschaubare $ Digest-Zyklen für alle anderen Ereignisse.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.