Optimierung der Leistung von JavaScript-Anwendungen für Anfänger

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

Einleitung: Warum ist die Leistung von JavaScript wichtig?

\n

JavaScript (insbesondere in der Node.js-Umgebung) ist zur Grundlage der modernen Webentwicklung geworden. Von der Ausführungsgeschwindigkeit des Codes hängen nicht nur die Benutzerfreundlichkeit, sondern auch die Serverlast ab. Langsame Anwendungen verlieren ihr Publikum, und nicht optimierte Anfragen können zu kostspieligen Kapazitätserweiterungen führen. In diesem Artikel werden wir grundlegende, aber effektive Methoden zur Leistungsoptimierung besprechen, die auch für Anfänger geeignet sind.

\n

Wir werden drei Schlüsselbereiche betrachten: asynchrone Programmierung, Arbeit mit dem Speicher und Profiling. Alle Beispiele basieren auf Node.js.

\n\n

1. Asynchronität: Blockierung der Event Loop vermeiden

\n

Node.js arbeitet im Single-Thread-Modus mit Hilfe der Event Loop. Wenn Sie eine synchrone, schwere Operation ausführen (z. B. das Lesen einer großen Datei oder eine komplexe Schleife), „hängt“ der gesamte Server, bis diese abgeschlossen ist. Um dies zu vermeiden, verwenden Sie asynchrone Methoden.

\n

Schlechtes Beispiel (blockierender Code):

\n
const fs = require('fs');\nconst data = fs.readFileSync('/bigfile.txt', 'utf8'); // Blockiert den Thread\nconsole.log('Datei gelesen');\n
\n

Gutes Beispiel (nicht blockierend):

\n
const fs = require('fs').promises;\nasync function readFile() {\n  const data = await fs.readFile('/bigfile.txt', 'utf8');\n  console.log('Datei gelesen');\n}\nreadFile();\n
\n

Verwenden Sie async/await und Promises für alle Ein-/Ausgabeoperationen (I/O). Dadurch kann die Event Loop andere Anfragen bearbeiten, während auf eine Antwort von der Datenbank oder dem Dateisystem gewartet wird.

\n

Tipp: Vermeiden Sie synchrone Methoden in der Produktion

\n

Methoden wie fs.readFileSync oder crypto.pbkdf2Sync sind nur beim Start der Anwendung zulässig. Verwenden Sie zur Laufzeit deren asynchrone Versionen.

\n\n

2. Optimierung der Speicherarbeit und Speicherlecks

\n

Speicherlecks sind eine der häufigsten Ursachen für Leistungseinbußen bei Node.js-Anwendungen. Sie treten auf, wenn Objekte im Speicher verbleiben, obwohl sie nicht mehr benötigt werden.

\n

Hauptursachen für Speicherlecks:

\n
    \n
  • Globale Variablen
  • \n
  • Nicht bereinigte Timer (setInterval ohne clearInterval)
  • \n
  • Geschlossene Referenzen in Closures
  • \n
  • Event-Listener, die nicht entfernt werden
  • \n
\n

Beispiel für ein Speicherleck durch Listener:

\n
const EventEmitter = require('events');\nconst emitter = new EventEmitter();\n\nfunction processRequest() {\n  emitter.on('data', (chunk) => {\n    // Datenverarbeitung\n  });\n}\n// Jeder Aufruf von processRequest fügt einen neuen Listener hinzu, entfernt aber den alten nicht!\n
\n

Lösung: Entfernen Sie Listener oder verwenden Sie once

\n
emitter.once('data', (chunk) => {\n  // Wird nur einmal ausgeführt und automatisch entfernt\n});\n
\n

Es ist auch nützlich, Hilfsprogramme wie heapdump zur Speicheranalyse zu verwenden. Für den Anfang reicht es jedoch aus, darauf zu achten, dass Referenzen auf Objekte nicht im globalen Gültigkeitsbereich verbleiben.

\n\n

3. Caching und Profiling

\n

Caching ermöglicht es, die wiederholte Ausführung aufwändiger Berechnungen zu vermeiden. Profiling hilft, Engpässe im Code zu finden.

\n

Einfaches Caching mit Map:

\n
const cache = new Map();\n\nfunction expensiveCalculation(input) {\n  if (cache.has(input)) {\n    console.log('Aus dem Cache');\n    return cache.get(input);\n  }\n  const result = input * 1000 + Math.random(); // Simulation komplexer Logik\n  cache.set(input, result);\n  return result;\n}\n\nconsole.log(expensiveCalculation(5)); // Berechnen\nconsole.log(expensiveCalculation(5)); // Aus dem Cache\n
\n

Für komplexere Szenarien verwenden Sie Bibliotheken wie node-cache oder Redis.

\n

Profiling mit dem integrierten Node.js-Tool

\n

Starten Sie die Anwendung mit dem Flag --prof:

\n
node --prof app.js\n
\n

Nach dem Stoppen der Anwendung erscheint im Ordner eine Datei isolate-*.log. Konvertieren Sie diese in ein

Blogs

Buchempfehlungen