更快的 WebSocket 压缩

· 功能

WebSocket 压缩对于减少带宽消耗和提升响应速度至关重要,尤其是在传输 JSON 等重复性数据时。permessage-deflate 扩展会即时压缩每个 WebSocket 帧——但压缩速度直接影响应用程序的吞吐量。

sgcWebSockets 2026.4.0 起,permessage-deflate 的实现已经过全面重写,性能显著提升。在我们的基准测试中,小消息的压缩和解压速度最高提升 15 倍,所有负载大小均有明显改善。

改动了什么?

之前的实现会在每个 WebSocket 帧上初始化并销毁压缩引擎。这意味着即使是 1 KB 的小消息,也要承担设置压缩器、压缩数据、再销毁的全部开销——下一条消息又要重复整个过程。

新实现让压缩引擎在帧间保持存活。它在第一个帧到来时初始化一次,并在整个连接生命周期内复用。这消除了每帧的初始化开销,同时允许引擎从之前的消息中学习,对重复数据模式实现更快的压缩。

除了持久化压缩上下文外,新实现还包含若干其他优化:

基准测试结果

我们对每种消息大小执行了 10,000 次压缩+解压往返测试。每次往返压缩一个 JSON 负载后再解压,并验证输出与原始内容一致。测试在 Windows 64 位机器上使用 Delphi 12 Athens 编译执行。

默认配置(持久化上下文)

这是默认模式,压缩上下文在帧间保持——也是最常见的实际场景:

消息大小 之前(毫秒) 之后(毫秒) 提速倍数
1 KB 437 ms 28 ms 快 15.6 倍
4 KB 480 ms 88 ms 快 5.5 倍
16 KB 546 ms 431 ms 快 1.3 倍
64 KB 1,994 ms 1,725 ms 快 1.2 倍

启用 NoContextTakeOver(独立帧)

当启用 NoContextTakeOver 时,每个帧独立压缩。即便在此模式下,缓冲区复用和直接内存访问优化仍带来显著提升:

消息大小 之前(毫秒) 之后(毫秒) 提速倍数
1 KB 149 ms 75 ms 快 2.0 倍
4 KB 173 ms 100 ms 快 1.7 倍
16 KB 302 ms 228 ms 快 1.3 倍
64 KB 1,216 ms 1,094 ms 快 1.1 倍

哪些场景受益最大?

对于频繁交换小消息的应用,改进效果最为显著——这正是 WebSocket 的典型使用场景:

聊天与即时通讯
短文本消息(通常低于 4 KB)的增益最大:压缩速度提升 5~15 倍。
实时数据推送
仪表盘、股票行情和 IoT 传感器的 JSON 更新,既受益于速度提升,又能利用持久化上下文对重复数据模式进行学习。
游戏与多人联机
频繁的小状态更新受益于较低的单帧开销。
高并发服务器
每帧 CPU 时间减少,服务器可处理更多并发连接。

完全兼容

此优化完全透明——您的应用无需任何代码修改。网络上传输的压缩数据与之前版本完全相同,因此升级后的服务器可与现有客户端无缝协作,反之亦然。

新实现支持所有平台和编译器:

升级至 2026.4.0

permessage-deflate 优化已在 sgcWebSockets 2026.4.0 中提供。只需更新至最新版本,您的 WebSocket 连接将自动受益于更快的压缩。请前往 esegece.com 下载。

特别感谢 Michael 贡献了最初的优化实现,启发了这项工作。他对持久化 zlib 上下文和直接内存访问的研究为这些性能改进奠定了基础。