Start · Sprachen · JavaScript · Referenz · new CompressionStream()

new CompressionStream()

Methode

Erstellt ein neues <code>CompressionStream</code>-Objekt, das einen Byte-Datenstrom mit gzip, deflate oder deflate-raw komprimiert.

seit JavaScript Baseline 2023: alle modernen Browser (Chrome 80+, Kategorie: webapi

Signatur

new CompressionStream(format)

Beschreibung

Der Konstruktor CompressionStream() erzeugt einen Transform-Stream aus der Compression Streams API. Er besteht aus einer beschreibbaren Seite (writable), die unkomprimierte Bytes annimmt, und einer lesbaren Seite (readable), die komprimierte Bytes liefert. Du verwendest ihn fast immer zusammen mit ReadableStream.prototype.pipeThrough().

Typische Einsatzfälle sind das Komprimieren großer Uploads vor dem Senden per fetch(), das Erzeugen von .gz-Dateien direkt im Browser, das platzsparende Ablegen von Daten in IndexedDB oder die Kompression von Protokoll- und Telemetriedaten. Da die Daten schrittweise (gestreamt) verarbeitet werden, muss nicht die ganze Eingabe gleichzeitig im Speicher liegen.

Wichtig: Der Stream arbeitet mit Bytes (ArrayBuffer, TypedArray, DataView). Zeichenketten musst du vorher kodieren, z. B. mit TextEncoderStream oder TextEncoder. Zum Entpacken dient das Gegenstück DecompressionStream.

Parameter

Name Typ Default Beschreibung
$format Pflicht "gzip" | "deflate" | "deflate-raw" Das Kompressionsformat: "gzip" (GZIP, RFC 1952), "deflate" (ZLIB, RFC 1950) oder "deflate-raw" (reines DEFLATE ohne Header/Prüfsumme, RFC 1951). Bei anderen Werten wird ein TypeError geworfen.

Rückgabewert

Typ
CompressionStream
Beschreibung
Ein neues CompressionStream-Objekt mit den Eigenschaften readable (ReadableStream mit komprimierten Bytes) und writable (WritableStream für Eingabebytes).

Beispiele

Text mit gzip komprimieren und Größe vergleichen

const compressText = async (text) => {
  const stream = new Blob([text]).stream()
    .pipeThrough(new CompressionStream('gzip'));
  return new Uint8Array(await new Response(stream).arrayBuffer());
};

const original = 'Hallo Welt! '.repeat(1000);
const gz = await compressText(original);
console.log(`Original: ${original.length} Bytes, gzip: ${gz.byteLength} Bytes`);
Original: 12000 Bytes, gzip: 77 Bytes (Wert kann leicht abweichen)

Komprimieren und wieder entpacken (Round-Trip)

const compress = (bytes, format = 'deflate') =>
  new Response(new Blob([bytes]).stream().pipeThrough(new CompressionStream(format))).arrayBuffer();

const decompress = (bytes, format = 'deflate') =>
  new Response(new Blob([bytes]).stream().pipeThrough(new DecompressionStream(format))).text();

const data = new TextEncoder().encode(JSON.stringify({ user: 'anna', items: [1, 2, 3] }));
const packed = await compress(data);
console.log(await decompress(packed));
{"user":"anna","items":[1,2,3]}

Datei im Browser als .gz herunterladen

const input = document.querySelector('input[type=file]');

input.addEventListener('change', async () => {
  const file = input.files[0];
  if (!file) return;

  const gzStream = file.stream().pipeThrough(new CompressionStream('gzip'));
  const blob = await new Response(gzStream).blob();

  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  a.download = `${file.name}.gz`;
  a.click();
  URL.revokeObjectURL(a.href);
});

Komprimierten Upload per fetch senden

const payload = JSON.stringify({ logs: Array.from({ length: 5000 }, (_, i) => `Eintrag ${i}`) });

const body = await new Response(
  new Blob([payload]).stream().pipeThrough(new CompressionStream('gzip'))
).blob();

const res = await fetch('/api/logs', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Encoding': 'gzip'
  },
  body
});
console.log(res.status);
200

// Wichtig · Fallstricke

  • Nur Bytes: Wenn du Strings direkt in writable schreibst, wird ein TypeError ausgelöst. Kodiere Text vorher mit TextEncoderStream bzw. TextEncoder oder wandle ihn über new Blob([text]).stream() um.
  • Ungültiges Format: Werte wie \"br\" oder \"zstd\" werfen einen TypeError. Brotli wird (noch) nicht unterstützt. Prüfe die Unterstützung bei Bedarf mit try { new CompressionStream('deflate-raw') } catch {}.
  • Formate nicht verwechseln: \"deflate\" meint ZLIB mit Header, nicht rohes DEFLATE. ZIP-Einträge nutzen \"deflate-raw\". Komprimiert und entpackt werden muss mit demselben Format, sonst schlägt DecompressionStream fehl.
  • Keine Kompressionsstufe: Kompressionsstufe, Fenstergröße und Wörterbuch lassen sich nicht einstellen. Für solche Feinsteuerung brauchst du Bibliotheken wie pako oder fflate bzw. in Node.js zlib.
  • Kompatibilität: Chrome/Edge 80+, Safari 16.4+, Firefox 113+. \"deflate-raw\" kam in Chrome erst mit Version 103. In Node.js ist die API ab Version 18 global verfügbar. Sie steht auch in Web Workern zur Verfügung.
  • Uploads: Mit Content-Encoding: gzip gesendete Anfragen muss der Server selbst entpacken. Viele Server tun das nicht automatisch. Bei bereits komprimierten Daten (JPEG, MP4, ZIP) bringt eine erneute Kompression kaum etwas.