Optimierung der Leistung von JavaScript-Anwendungen: Ein praktischer Leitfaden

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

Optimierung der Leistung von JavaScript-Anwendungen: In der Praxis



Die Leistung von JavaScript-Anwendungen ist nicht nur ein netter Bonus, sondern ein kritischer Faktor, der die Benutzererfahrung (UX), die Conversion-Rate und die Infrastrukturkosten beeinflusst. Ein langsamer Seitenaufbau oder eine Verzögerung bei API-Antworten können Sie bis zu 40 % Ihres Traffics kosten. In diesem Artikel betrachten wir praktische Methoden zur Optimierung von JavaScript-Code (in der Node.js-Umgebung), die Ihnen helfen, Ihre Anwendung schneller und effizienter zu machen. Wir werden nicht tief in die theoretischen Grundlagen des Event Loops eintauchen, sondern direkt zu konkreten Techniken mit Beispielen übergehen.



1. Caching: Serverlast reduzieren



Eine der effektivsten Methoden, eine Anwendung zu beschleunigen, besteht darin, die wiederholte Ausführung teurer Operationen zu vermeiden. Caching ermöglicht es, das Ergebnis von Berechnungen oder Datenbankabfragen zu speichern und bei erneuten Anfragen auszuliefern.



In-Memory-Caching mit Map

Für einfache Szenarien, in denen Daten keine komplexe Invalidierungslogik erfordern, eignet sich das integrierte Map-Objekt ideal. Es ist schneller als Object und besser geeignet für häufiges Hinzufügen und Entfernen von Schlüsseln.



const cache = new Map();

async function fetchUserData(userId) { if (cache.has(userId)) { console.log('Aus dem Cache zurückgegeben'); return cache.get(userId); }

// Simulation einer teuren DB-Abfrage const data = await new Promise((resolve) => { setTimeout(() => resolve({ id: userId, name: `User_${userId}` }), 1000); });

cache.set(userId, data); return data;}

// Erster Aufruf (warte 1 Sek.)console.time('first');await fetchUserData(1);console.timeEnd('first');

// Zweiter Aufruf (sofort)console.time('second');await fetchUserData(1);console.timeEnd('second');


TTL (Time-To-Live) Cache

Damit der Cache nicht veraltet, muss eine Lebensdauer für die Einträge hinzugefügt werden. Wir implementieren einen einfachen TTL-Cache.



class TTLMap {  constructor(ttlMs = 60000) {    this.ttl = ttlMs;    this.store = new Map();  }

set(key, value) { const record = { value, expiry: Date.now() + this.ttl }; this.store.set(key, record); }

get(key) { const record = this.store.get(key); if (!record) return null; if (Date.now() > record.expiry) { this.store.delete(key); return null; } return record.value; }}

const userCache = new TTLMap(5000); // Cache für 5 Sekunden


2. Asynchronität und Optimierung des Event Loops



Node.js ist single-threaded, aber seine asynchrone Natur ermöglicht die effiziente Verarbeitung vieler Anfragen. Der Hauptfeind der Leistung sind synchrone Operationen, die den Event Loop blockieren.



Vermeiden Sie synchrone Versionen von Funktionen

Die Module fs, crypto und andere haben synchrone Gegenstücke (readFileSync, crypto.pbkdf2Sync). Verwenden Sie diese nur beim Initialisieren der Anwendung. Innerhalb von Request-Handlern sollten ausschließlich asynchrone Versionen verwendet werden.



// SCHLECHT: Blockiert den Event Loopconst data = fs.readFileSync('/path/to/file.txt', 'utf-8');

// GUT: Asynchronconst data = await fs.promises.readFile('/path/to/file.txt', 'utf-8');


Teilen Sie schwere Aufgaben mit setImmediate auf

Wenn Sie eine schwere synchrone Schleife haben (z. B. die Verarbeitung eines Arrays mit 10 Millionen Elementen), blockiert diese den Server für mehrere Sekunden. Teilen Sie die Aufgabe in Teile auf und verwenden Sie setImmediate, um dem Event Loop die Möglichkeit zu geben, zwischen den Teilen andere Anfragen zu bearbeiten.



function processLargeArray(items, chunkSize = 1000) {  let index = 0;

function processChunk() { const chunk = items.slice(index, index + chunkSize); // Verarbeite den Teil chunk.forEach(item => heavyOperation(item));

index += chunkSize; if (index < items.length) { // Fahre in der nächsten Iteration des Event Loops fort

Blogs

Buchempfehlungen