JavaScript gegen Gigabyte: Wie der Browser Big Data verarbeitet

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

Wenn der Browser kein Spielzeug, sondern ein Rechenzentrum ist

\n\n

Wir sind es gewohnt, dass JavaScript in der Browser-Sandbox lebt: Animationen, Klicks, Formulare. Aber was, wenn ich Ihnen sage, dass man mit reinem JS eine 500 MB große CSV-Datei verarbeiten, ein Diagramm mit 100.000 Punkten erstellen und den Tab nicht zum Absturz bringen kann? Das ist keine Science-Fiction, sondern der gekonnte Einsatz von Verarbeitung großer Datenmengen mit JavaScript.

\n

In diesem Artikel zeige ich Ihnen, wie Sie direkt im Browser mit großen Datenmengen arbeiten – ohne Backend, ohne Python, ohne Gigabyte auf den Server zu kopieren. Sie erfahren mehr über Streaming, Web Workers, Speicheroptimierung und Bibliotheken, die den Browser in einen Mini-Datenprozessor verwandeln. Los geht's!

\n\n

Warum „naive“ Datenverarbeitung die Leistung tötet

\n

Stellen Sie sich vor: Sie laden eine 300 MB große CSV-Datei und schreiben:

\n
const data = await response.json(); // ❌ Fataler Fehler
\n

Was passiert? JS versucht, die gesamte Datei in den Arbeitsspeicher zu parsen. Wenn der Benutzer 4 GB RAM hat – stürzt der Browser ab. Selbst auf einem leistungsstarken PC beginnt der Garbage Collector zu „trödeln“ und die Oberfläche friert für eine Minute ein.

\n

Regel Nr. 1: Laden Sie nicht alles auf einmal. Große Datenmengen in JavaScript erfordern eine Stream-Verarbeitung (Streaming) und die Aufteilung in Chunks.

\n\n

Daten-Streaming: Datei stückweise lesen

\n

Die Browser-API FileReader ermöglicht das Lesen einer Datei in Teilen. Noch praktischer ist jedoch ReadableStream. Beispiel: Verarbeitung einer großen JSON-Datei zeilenweise.

\n\n

Beispiel: JSON-Streaming mit NDJSON

\n

Das NDJSON-Format (jede Zeile ist ein separates JSON-Objekt) ist ideal für große Datenmengen. So lesen Sie es als Stream:

\n
async function* streamJSON(file) {\n  const stream = file.stream();\n  const reader = stream.getReader();\n  const decoder = new TextDecoder();\n  let buffer = '';\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    buffer += decoder.decode(value, { stream: true });\n    const lines = buffer.split('\\n');\n    buffer = lines.pop(); // Rest in den Puffer\n    for (const line of lines) {\n      if (line.trim()) yield JSON.parse(line);\n    }\n  }\n}\n\n// Verwendung\nfor await (const obj of streamJSON(selectedFile)) {\n  processRow(obj); // Ein Objekt nach dem anderen verarbeiten\n}\n
\n

Der Speicher wächst kaum – wir behalten nur eine Zeile im Speicher. Dieser Ansatz ist die Grundlage der Verarbeitung großer Datenmengen mit JavaScript in realen Projekten.

\n\n

Web Workers: Die Oberfläche nicht einfrieren

\n

Auch Streaming wird im Hauptthread ausgeführt. Wenn die Berechnungen komplex sind, friert die UI ein. Lösung: Web Workers. Dies ist ein separater Thread, in dem Gigabyte ohne Verzögerungen verarbeitet werden können.

\n\n

Worker zur CSV-Verarbeitung erstellen

\n

Worker-Code (worker.js):

\n
self.onmessage = async function(e) {\n  const { file, chunkSize } = e.data;\n  const reader = new FileReaderSync(); // Synchrones Lesen – für Worker erlaubt\n  let offset = 0;\n  const results = [];\n\n  while (offset < file.size) {\n    const blob = file.slice(offset, offset + chunkSize);\n    const text = reader.readAsText(blob);\n    const lines = text.split('\\n');\n    for (const line of lines) {\n      if (line.trim()) results.push(parseCSVLine(line));\n    }\n    offset += chunkSize;\n    // Zwischenergebnis senden\n    self.postMessage({ type: 'chunk', data: results.splice(0, results.length) });\n  }\n  self.postMessage({ type: 'done' });\n};\n\nfunction parseCSVLine(line) {\n  const [name, age, city] = line.split(',');\n  return { name, age: parseInt(age), city };\n}\n
\n

Hauptthread:

\n
const worker = new Worker('worker.js');\nworker.postMessage({ file: csvFile, chunkSize: 1024 * 1024 }); // 1 MB Chunks\n\nworker.onmessage = (e) => {\n  if (e.data.type === 'chunk') {\n    updateUI(e.data.data); // Tabelle/Diagramm fließend aktualisieren\n  }\n};\n
\n

Jetzt bleibt die Oberfläche reaktionsfähig, selbst wenn wir 2 GB Daten verarbeiten. Dies ist eine Schlüsseltechnik für b

Blogs

Buchempfehlungen