You're importing pako to gzip data. `CompressionStream` does it natively.
DEV Community

You're importing pako to gzip data. CompressionStream does it natively.

Compressing data before writing it to IndexedDB or sending it over a slow connection is a real optimization. When a cached API response is too large for reliable storage, or when you need to shrink a JSON payload before POSTing it, pako.gzip() is the standard reach. But pako is a pure-JavaScript port of zlib - written in user space to fill a gap the browser had at the time. The CompressionStream API is that gap closing. The API CompressionStream is a transform stream - data goes in one end, compressed data comes out the other. The constructor takes a format string: 'gzip' , 'deflate' , or 'deflate-raw' . const stream = new CompressionStream('gzip'); DecompressionStream is the mirror: const stream = new DecompressionStream('gzip'); The Streams plumbing to feed data in and collect it out is the verbose part. Wrap it once: async function compress(input, format = 'gzip') { const stream = new Blob([input]).stream().pipeThrough(new CompressionStream(format)); return new Uint8Array(await new Response(stream).arrayBuffer()); } async function decompress(input, format = 'gzip') { const stream = new Blob([input]).stream().pipeThrough(new DecompressionStream(format)); return new Response(stream).text(); } Blob.stream().pipeThrough() feeds the data into the transform stream; new Response(stream) collects the result. The idiom is three lines of plumbing written once, then call sites that read plainly. Replacing pako A direct swap for the most common pako usage patterns: // Before - pako import pako from 'pako'; const compressed = pako.gzip(jsonString); // Uint8Array const restored = pako.ungzip(compressed, { to: 'string' }); // After - native const compressed = await compress(jsonString); // Uint8Array const restored = await decompress(compressed); // string The output is the same gzip-format Uint8Array . Any system that accepts pako's output accepts the native output - the wire format is identical. Real-world patterns Storing large JSON in IndexedDB: async function putCompressed(store, key, data) { const compressed = await compress(JSON.stringify(data)); return store.put(compressed, key); } async function getCompressed(store, key) { const compressed = await store.get(key); if (!compressed) return null; return JSON.parse(await decompress(compressed)); } A 200 KB JSON object typically compresses to 15-30 KB with gzip. For quota-constrained storage like IndexedDB on mobile browsers, that difference matters. Compressing in a Web Worker: // worker.js self.onmessage = async ({ data }) => { const compressed = await compress(JSON.stringify(data.payload)); self.postMessage({ compressed }, [compressed.buffer]); }; CompressionStream works in Web Workers and Service Workers - the same API, the same two-function wrapper, no restrictions. Offloading compression to a worker keeps the main thread free. Format reference The three supported formats map directly to pako's methods: CompressionStream format | pako equivalent | When to use | |---|---|---| 'gzip' | pako.gzip / pako.ungzip | HTTP transport, file storage - the standard | 'deflate' | pako.deflate / pako.inflate | zlib-wrapped deflate | 'deflate-raw' | pako.deflateRaw / pako.inflateRaw | raw DEFLATE, no wrapper header | 'gzip' is the right default for most use cases. Use 'deflate-raw' only when interoperating with a system that expects unwrapped DEFLATE. Performance CompressionStream calls into the browser's native zlib implementation - the same C code path used when the browser decompresses HTTP responses with Content-Encoding: gzip . pako re-implements that algorithm in JavaScript. The native path is measurably faster on large inputs: - For small payloads (< 10 KB), the difference is negligible. - For large payloads (100 KB+), native compression is typically 3-10ร— faster than pako, because there's no JavaScript overhead and the engine can use SIMD instructions. - There's also no bundle cost: pako adds ~45 KB minified to your bundle; CompressionStream adds zero. Node.js CompressionStream and DecompressionStream are available in Node.js 18.0 as part of the Web Streams implementation. The two-function wrapper above works unchanged in Node 18+ - useful for isomorphic utilities that run in both browser and server environments without branching on the environment. Node's older zlib module (zlib.gzipSync , zlib.gunzipSync ) is still more ergonomic for Node-only server code. But if you're writing a shared utility that must work in both contexts, CompressionStream is the right choice. Browser support CompressionStream is Baseline 2023: Chrome 80 (February 2020), Firefox 113 (May 2023), Safari 16.4 (March 2023), Node.js 18. The API has been in Chromium since early 2020; Firefox and Safari joined in 2023. It's available in all currently-supported browser and runtime versions, including Web Workers and Service Workers. ๐ŸŽฎ Try it yourself โ–ถ๏ธ Open the interactive playground โ†’ Runs right in your browser - poke at it and watch the concept react live. ๐Ÿง  Test yourself Think it clicked? Take the 9-question quiz โ†’ Instant feedback, a hint on every question, and an explanation for each answer - right or wrong. The takeaway Search your package.json for pako . If it's there and the use case is "compress a string or buffer before storing or sending it," the native API covers you. Replace pako.gzip and pako.ungzip with the two-function wrapper above, remove the dependency, and get native compression speed and zero bundle cost. The Streams API is verbose on its own - the wrapper absorbs that cost once so every call site stays clean. Thanks for reading! Let's stay connected: - โญ GitHub - follow me and star the projects: github.com/parsajiravand - ๐Ÿ’ฌ Discord - join the frontend best-practices community: discord.gg/d9KRhuAwQ - ๐Ÿ“ธ Instagram - frontend best practices, daily: @bestpractice___ - ๐Ÿ’ผ LinkedIn - linkedin.com/in/parsa-jiravand - โœ‰๏ธ Email (work & contract inquiries): bes*************@gmail.com Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.