Profiling von JavaScript-Code: Engpässe in Node.js finden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Profiling von JavaScript-Code: Engpässe in Node.js finden



Die Geschwindigkeit einer Anwendung ist einer der Schlüsselfaktoren für den Erfolg. Selbst perfekt geschriebener Code kann mit der Zeit aufgrund von steigender Last, ineffizienten Algorithmen oder Speicherlecks anfangen zu "trödeln". In der Welt von Node.js und JavaScript hilft das Profiling, die Ursache von Verlangsamungen zu finden. In diesem Artikel analysieren wir, wie man mit integrierten und externen Tools Engpässe identifiziert, und geben praktische Beispiele.



Was ist Profiling und warum wird es benötigt?



Profiling ist der Prozess der Datenerfassung darüber, wie ein Programm Ressourcen nutzt: Prozessorzeit, Speicher, Funktionsaufrufe. Der Profiler zeichnet auf, welche Funktionen am längsten ausgeführt werden und wie oft sie aufgerufen werden. Dies ermöglicht es dem Entwickler, nicht zu raten, sondern genau zu wissen, welcher Codeabschnitt optimiert werden muss.



Die Hauptziele des Profilings:

  • Identifizierung von "Hotspots" – Codeabschnitten, die die meiste Zeit verbrauchen.
  • Suche nach Speicherlecks.
  • Optimierung von Algorithmen und Datenstrukturen.
  • Überprüfung der Effizienz asynchroner Operationen.


Integrierter Profiler von Node.js (V8)



Node.js wird mit einem integrierten Profiler auf Basis der V8-Engine ausgeliefert. Er ermöglicht das Sammeln von Aufrufstapeln und Ausführungszeiten von Funktionen ohne Installation zusätzlicher Pakete.



Starten Sie Ihre Anwendung mit dem Flag --prof:



node --prof app.js


Nach Beendigung des Programms erscheint im aktuellen Ordner eine Datei namens isolate-0x...-v8.log (oder ähnlich). Um einen lesbaren Bericht zu erhalten, verarbeiten Sie diese:



node --prof-process isolate-0x...-v8.log > processed.txt


Beispielausgabe (vereinfacht):



Statistical profiling result from isolate-0x... [Shared libraries]:   ticks  total  nonlib   name   100    50.0%           node::Start

[JavaScript]: ticks total nonlib name 40 20.0% 40.0% LazyCompile: *slowFunction /path/to/file.js:10 20 10.0% 20.0% LazyCompile: *fastFunction /path/to/file.js:5


Hier steht ticks für die Anzahl der "Ticks" (Messungen), in denen die Funktion beobachtet wurde. Je mehr ticks, desto "schwerer" die Funktion. Im Beispiel belegt slowFunction 40% der Zeit.



Wichtig: Der integrierte Profiler liefert ein statistisches (stichprobenartiges) Bild, das für sehr schnelle Funktionen ungenau sein kann.



Profiling über Chrome DevTools



Für eine anschaulichere Analyse können Sie Chrome DevTools verwenden. Node.js unterstützt ein spezielles Debug-Protokoll, das den Anschluss von Browser-Werkzeugen ermöglicht.



Starten Sie Node.js mit dem Flag --inspect:



node --inspect app.js


In der Konsole erscheint ein Link der Form chrome-devtools://devtools/bundled/.... Öffnen Sie ihn im Chrome-Browser. Sie gelangen in die bekannte DevTools-Oberfläche, die jedoch an Ihren Node.js-Prozess gebunden ist.



Auf dem Tab Profiler (oder Performance) können Sie:

  • Ein Ausführungsprofil aufzeichnen (Start → Stop).
  • Ein Flame Graph (Flammendiagramm) anzeigen, bei dem die Breite eines "Balkens" die Ausführungszeit der Funktion darstellt.
  • Aufrufe in der Bottom-Up- oder Tree-Ansicht analysieren.


Beispielcode zum Testen:



// app.jsfunction heavyComputation() {    let sum = 0;    for (let i = 0; i < 1e7; i++) {        sum += Math.sqrt(i);    }    return sum;}

function main() { console.time('heavy'); const result = heavyComputation(); console.timeEnd('heavy'); console.log(result);}

main();


Nach der Aufzeichnung des Profils in DevTools werden Sie sehen, dass heavyComputation fast 100% der Zeit belegt – das ist der Engpass.



Fortschrittliches Werkzeug: c

Blogs

Buchempfehlungen