Kategorien
JavaScript & jQuery Programmierung

JavaScript: Bessere Auswertung der Performance durch User Marks

Wer an fortgeschrittenem JavaScript-Code arbeitet, wie zum Beispiel einer 3D-Engine, wird sich früher oder später fragen, wie sich dieser Code optimieren lässt und wie viel Zeit man mit bestimmten Abschnitten des Codes verbringen sollte. In diesem Tutorial stelle ich einige Tools vor, die uns sagen, wie gut die Performance unseres Codes tatsächlich ist und wie wir Anwendermarkierungen (User Marks) im Memory Graph am besten nutzen, um die Leistungsfähigkeit des Codes auszuwerten.

JavaScript: Bessere Auswertung der Performance durch User Marks

Sie wollen einen schnellen Überlick zum Thema? Dann gleich mal dieses Video ansehen.

Wer Fragen zu diesem Artikel hat, kann mich gern auf Twitter kontaktieren (@deltakosh)

Profiler gesucht?

Dazu fällt mir gleich der integrierte Profiler ein, der in den Updates zu den Internet Explorer F12 Dev Tools enthalten ist — dessen Weiterentwicklung, die auch für Microsoft Edge verfügbar sind. Aber natürlich sind andere, ähnlich funktionale Tools ebenso geeignet.

Wer das mal mit Android, iOS oder Mac OS ausprobieren will, kann auch remote.IE nutzen, um eine Windows 10 Technical Preview-Instanz in wenigen Minuten zum Laufen zu bringen. Dann einfach den Internet Explorer “e” öffnen (eine temporäre Client Shell mit konfigurierter neuer Rendering Engine von Microsoft Edge), “F12” klicken und daraufhin sollte das Folgende zu sehen sein:

Hierbei ist zu beachten, dass bei den neuen F12 Tools, die Teil des Windows 10 Technical Previews sind, der Profiler im Fenster „UI responsiveness“ zu finden ist:

Schauen wir uns nun andere Optionen an, die uns Erkenntnisse über die Performance unseres Codes vermitteln können.

console.time

Hier muss man einfach nur console.time() und console.timeEnd() vor bzw. nach dem Teil des Codes aufrufen, der getestet werden soll. Als Ergebnis erhält man einen String in der Konsole, der die Zeit zwischen time und timeEnd anzeigt.

Natürlich ist das recht einfach und kann auch leicht emuliert werden, aber mir persönlich gefällt besonders die Unkompliziertheit dieser Funktion.

Und es kommt noch besser: Man kann einen String angeben, um eine Bezeichnung für die Messwerte zu bekommen.

Dies habe ich zum Beispiel für Babylon.js getan:

console.time("Active meshes evaluation");
this._evaluateActiveMeshes();
console.timeEnd("Active meshes evaluation");

Diese Art von Code ist in allen wichtigen Funktionen zu finden und wenn man Performance Logging aktiviert hat, erhält man jede Menge interessanter Informationen:

Hinweis: Das Rendering von Text in die Konsole kann eine Menge CPU-Power beanspruchen.

Da diese Funktion an sich keine Standardfunktion ist, hat mich die Kompatibilität mit unterschiedlichen Browsern umso mehr überzeugt. Sie wird von Chrome, Firefox, IE, Opera und Safari unterstützt.

Performance Object

Wer es gern etwas visueller mag, dem sei performance object empfohlen. Neben anderen interessanten Features, um die Performance einer Webseite zu messen, gibt es die Funktion mark, die eine Anwendermarkierung (user mark) aussendet.

Eine Anwendermarkierung verbindet einen Namen mit einem Zeitwert. Teile des Codes können mit dieser API gemessen werden, um genaue Werte zu erhalten. Es gibt einen tollen Artikel über diese API von Aurelio de Rosa bei SitePoint.

An dieser Stelle hier geht es mir nur darum, diese API zu benutzen, um konkrete Anwendermarkierungen im UI Responsiveness Screen bildlich darzustellen:

Dieses Tool ermöglicht es, eine Session zu erfassen und festzustellen, wie stark dabei die CPU beansprucht wird:

Wir können dann einen konkreten Frame vergrößert darstellen, indem wir den Eintrag “Animation frame callback” auswählen und dort nach einem Rechtsklick “filter to event” wählen.

Der gewählte Frame wird daraufhin gefiltert:

Dank des neuen F12 Tools können wir nun zu den JavaScript Call Stacks wechseln, um mehr Details zu diesem Event zu bekommen:

Es ist an dieser Stelle jedoch etwas schwierig, zu erkennen, wie der Code während des Events tatsächlich umgesetzt wurde.

Hier jedoch helfen uns die User Marks aus der Klemme. Wir können unsere eigenen Marker hinzufügen und sind dann in der Lage einen Frame aufzuteilen. Dort können wir dann analysieren, welches Feature am aufwändigsten ist.

performance.mark("Begin of something…just now!");

Wer ein eigenes Framework erstellt, erhält daduch außerdem die sehr praktische Möglichkeit, den eigenen Code mit Messwerten zu belegen:

performance.mark("Active meshes evaluation-Begin");
this._evaluateActiveMeshes();
performance.mark("Active meshes evaluation-End");
performance.measure("Active meshes evaluation", "Active meshes evaluation-Begin", "Active meshes evaluation-End");

Schauen wir uns doch mal an, was uns das bei babylon.js bringt, hier für die Instanz mit der “V8”-Szene:

Wir können nun babylon.js auffordern, für uns User Marks und Messwerte auszusenden. Dazu benutzen wir den debug layer:

Mithilfe des UI Responsiveness Analyzer erhalten wir diese Ansicht:

Deutlich zu sehen: Die User Marks werden oberhalb des Events angezeigt (die orangefarbenen Dreiecke), ebenso die Bereiche für alle Messungen:

Auf diese Weise lässt sich in diesem Beispiel sehr leicht bestimmen, dass die Abschnitte [Render targets] und [Main render] am aufwändigsten operieren.

Der vollständige Code, den babylon.js nutzt, um den Usern zu ermöglichen, die Performance verschiedener Funktionen zu testen, sieht so aus:

  Tools._StartUserMark = function (counterName, condition) {
    if (typeof condition === "undefined") { condition = true; }
    if (!condition || !Tools._performance.mark) {
        return;
    }
    Tools._performance.mark(counterName + "-Begin");
};

Tools._EndUserMark = function (counterName, condition) {
    if (typeof condition === "undefined") { condition = true; }
    if (!condition || !Tools._performance.mark) {
        return;
    }
    Tools._performance.mark(counterName + "-End");
    Tools._performance.measure(counterName, counterName + "-Begin", counterName + "-End");
};

Tools._StartPerformanceConsole = function (counterName, condition) {
    if (typeof condition === "undefined") { condition = true; }
    if (!condition) {
        return;
    }

    Tools._StartUserMark(counterName, condition);

    if (console.time) {
        console.time(counterName);
    }
};

Tools._EndPerformanceConsole = function (counterName, condition) {
    if (typeof condition === "undefined") { condition = true; }
    if (!condition) {
        return;
    }

    Tools._EndUserMark(counterName, condition);

    if (console.time) {
        console.timeEnd(counterName);
    }
};

Dank der F12 Tools und den User Marks erhalten wir also ein sehr nützliches Dashboard, das uns zeigt, wie effizient verschiedene Teile des Codes zusammenarbeiten.

Mehr Tipps, Tricks und Hilfen rund um JavaScript

Microsoft hält eine ganze Reihe kostenloser Lehrangebote zu zahlreichen Open Source JavaScript-Themen bereit – und seit der Veröffentlichung von Microsoft Edge tun wir in diesem Bereich noch sehr viel mehr. Auch von mir gibt es Tutorials:

Außerdem haben wir noch die Schulungsreihe unseres Teams:

Praktisch sind zudem die folgenden kostenlosen Tools: Visual Studio Community, Azure Testversion sowie Cross Browser Testing Tools für Mac, Linux oder Windows.

Dieser Artikel ist Teil der Web-Dev Tech-Series von Microsoft. Wir freuen uns Microsoft Edge (früher Project Spartan genannt) und seine neue Rendering Engine mit euch zu teilen. Kostenlose Virtual Machines oder Remote Testings für Mac, iOS, Android oder Windows gibt es hier: @ dev.modern.IE.

(dpe)

Von David Catuhe

David Catuhe ist Principal Program Manager bei Microsoft mit einem Fokus auf Web-Entwicklung. Er ist der Autor des babylon.js Frameworks, mit dem man 3D Spiele mit HTML5 and WebGL erstellen kann.

Lesen Sie seinen Blog auf MSDN oder folgen Sie ihm auf Twitter: @deltakosh

3 Antworten auf „JavaScript: Bessere Auswertung der Performance durch User Marks“

Danke für diesen Artikel.
Das Theme ist anfürsich wirklich schön, aber im IE11 lassen sich die Seiten nicht scrollen (zumindest nicht bei mir). Schade

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.