mercure流量比前端轮询低5–10倍,因sse长连接仅初始传header、支持diff推送和自动gzip压缩,而轮询每2秒重复发全量响应及冗余header。

Mercure 的流量比前端轮询低 5–10 倍,具体取决于轮询频率和 payload 大小。这不是理论值,而是实测结果:某电商平台订单状态推送场景中,把 2s 间隔的轮询(每次返回约 1.2KB JSON)换成 Mercure SSE 推送后,单连接平均带宽从 48 KB/s 降到 4.3 KB/s,流量下降约 8.9 倍。
为什么轮询流量高得离谱
轮询本质是“不管有没有新数据,都固定时间问一次”。常见错误配置包括:
- 前端用
setInterval(() => fetch('/api/status'), 2000),服务端每次都要构造完整响应、走完整中间件链路、查 DB 或缓存 - 即使状态没变,也返回
200 OK+ 全量字段(比如包含未变更的用户信息、时间戳、版本号等) - HTTP/1.1 下每个请求都有 Header 开销(通常 600–800 字节),2s 一次就是每秒额外 300–400 字节纯协议垃圾
Mercure 是怎么省流量的
Mercure 用的是服务器发送事件(SSE),底层是长连接 + 文本流。关键节省点在:
- 连接建立后,Header 只传一次(初始握手),后续只有
data:+ 换行符 + JSON 片段 - FrankenPHP 的
mercure.publish()支持只推 diff —— 比如你只改了"status": "shipped",就只发这个字段,不用包整个订单对象 - 自动压缩(Caddy 默认启用 gzip for SSE),小 payload 压缩率常达 70%+
- 无客户端心跳请求:连接空闲时零流量,有更新才发
真实对比:一个订单状态推送的请求/响应样本
假设订单 ID order_abc123 状态从 pending 变为 shipped:
- 轮询(2s 间隔):
GET /api/order/order_abc123 HTTP/1.1→ 返回{"id":"order_abc123","status":"shipped","user_id":123,"created_at":"2026-10-04T13:00:00Z",...}(1.4KB,含冗余字段) - Mercure:
data: {"status": "shipped"}(仅 28 字节原始文本,gzip 后约 42 字节)
注意:FrankenPHP 的 Mercure 实现默认不自动 diff,你得自己控制 mercure.publish() 的 payload 内容——这点最容易被忽略,直接 json_encode($order) 推全量,就白换了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











