配了三年数据压缩,每次上线都要接一个 30KB 的库——今天浏览器自己会了
每次做离线缓存都要 npm install 一个压缩库,打包体积因此多了 30KB——今天这件事被浏览器自己的 API 彻底原生化了。
Compression Streams API 做的事情很简单:给浏览器内置 gzip/deflate 压缩和解压,pipeThrough 一行搞定,不用任何 npm 依赖。
核心用法就两行:
// 压缩:fetch 拿数据 → gzip 压缩 → 存 IndexedDB
const compressed = readableStream.pipeThrough(new CompressionStream('gzip'));
// 解压:读出来 → gzip 解压 → 正常使用
const decompressed = compressed.pipeThrough(new DecompressionStream('gzip'));
解压缩格式支持 "gzip"、"deflate"、"deflate-raw" 三种,大多数场景用 "gzip" 就够了。
为什么这事值得一说
你之前很可能已经用过它——Workbox 的 Service Worker 缓存、Cloudflare Workers 的响应压缩,底层都在悄悄用 Compression Streams。但因为 Safari 长期不支持,这事没法在生产环境默认开启。
现在是 2026 年 9 月,全球 95% 的浏览器已经覆盖(Chrome 80+、Safari 16.4+、Firefox 113+),Safari 26 之后彻底完成三引擎统一。意味着你可以直接在项目里用,删掉 pako 了。
三个真实场景
第一个是离线数据同步。很多 App 会把 API 响应缓存进 IndexedDB,之前要靠 pako 压缩才能控制在合理体积。现在直接:
// 存进去之前压缩
const cs = new CompressionStream('gzip');
response.body.pipeThrough(cs).pipeTo(writable);
第二个是 Service Worker 缓存预压缩。你可以在构建时预先生成 .gz 文件,SW 直接返回预压缩流,省掉服务器的 on-the-fly 压缩:
const cached = await caches.match(url);
const enc = new CompressionStream('gzip');
cached.body.pipeThrough(enc); // SW 直接吐压缩流
第三个是前后端通信数据压缩。如果你有 WebSocket 实时推送大量 JSON 的场景,压缩后再传输,体积能降 60-80%。
性能和兼容性问题
Compression Streams 用的是浏览器原生实现,压缩率和你用 pako 差不多,但速度更快(原生 C++ vs JS)。实测 gzip 压缩 1MB JSON,Chrome 大约快 3-5 倍。
不过有两个注意事项:
一是它只支持流式处理,不支持同步压缩。如果你要压缩一个完整的 ArrayBuffer,需要先转成 ReadableStream。这在使用时略有门槛。
二是 Safari 16.4 开始支持,但 iOS 16.4 之前的系统仍占约 4% 全球份额,老机型还是要渐进增强。
下一步
先跑一遍你的 package.json,看看有没有 pako、flate、jszip 这几个包——如果有,说明数据压缩场景已经存在,可以直接替换。如果没用这些库,检查一下你的 SW 缓存策略,现在可以默认开启预压缩了。
评论区
登录后可评论。