WebSocket 流量需在应用层手动统计 send() 和 onmessage 的字节数:文本用 TextEncoder.encode(str).length(UTF-8),二进制取 .byteLength/.size;Chrome Network 面板仅显示握手请求,不统计后续帧数据。

WebSocket 流量消耗不能靠 Network 面板直接读准,必须在应用层手动统计 send() 和 onmessage 中的字节数,否则看到的只是连接建立阶段的 HTTP Upgrade 请求,后续帧级数据全被隐藏。
如何在 JS 中准确统计每次 send / receive 的字节数
浏览器不提供现成的“已发送字节”API,得自己算。关键不是看字符串长度,而是编码后的实际字节长度:
-
TextEncoder是标准方式:对文本消息用new TextEncoder().encode(str).length,它按 UTF-8 编码计数,和真实网络开销一致 - 二进制类型(
ArrayBuffer、Blob)直接取.byteLength或.size,别用JSON.stringify().length—— 那会多出引号、转义符,严重高估 - 注意
event.data类型可能是string、ArrayBuffer或Blob,需先判断再处理,否则.byteLength会是undefined
为什么 Chrome DevTools 的 Network 面板显示的 ws 流量不准
Network 面板里 WebSocket 条目只显示握手请求(HTTP 101),之后所有帧都不计入“Size”列。你看到的“1.2 KB”可能只是 Upgrade 头,而实际传输了 5 MB 消息也不会体现。
- Chrome 110+ 虽支持
WebSocketFrame事件,但仅在 Performance 面板中可见,且不汇总字节数,只标时间戳 - Network → Filter →
ws只能查连接建立耗时、关闭码(如1006)、是否走 TLS,无法用于流量审计 - 真要抓帧内容,得切到 Performance 面板录制后筛选
WebSocketFrame,再手动加总,效率极低且不可编程
生产环境必须采样上报,否则监控本身拖慢业务
高频消息场景下(比如每秒 20+ 帧),全量计算 + 上报会阻塞主线程,尤其在低端安卓机上明显卡顿。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 用
Math.random() 实现 5% 采样,对抽中的消息才执行TextEncoder编码和上报逻辑 - 上报必须异步:存入内存队列,用
requestIdleCallback或setTimeout(..., 0)触发,避免影响渲染帧 - 上报字段严格精简:只传
{type: "chat", dir: "out", size: 1248, delay: 42, connId: "ws_abc123", ts: 1748194200123},禁止带原始 payload
Kubeshark 和 Proxyee 这类工具适合什么人用
它们不替代前端埋点,而是补充服务端或中间层视角。Kubeshark 的 ws_request_payload_length 字段来自代理解包,Proxyee 的拦截器则依赖 MITM 解密 HTTPS 流量 —— 这两类方案都要求部署权限,且无法获取客户端真实处理延迟(比如 JS 解析慢、UI 更新卡顿)。
- 前端团队没权限改 nginx 或部署代理?只能靠自己埋点
- 想对比“发出去多少”和“服务端收到多少”?需要前后端打标对齐
msg_id,光靠工具看不到链路断点 - Kubeshark 的
ws_opcode == "binary"过滤很好用,但它统计的是 wire-level 字节数,不含应用层压缩(如 gzip 后再 send),这点容易误判带宽压力
最常被忽略的一点:很多人把 event.data 当成字符串直接 .length,结果在传输 emoji 或中文时少算近一倍字节——UTF-8 下一个汉字占 3 字节,"?".length 是 2,但 TextEncoder.encode("?").length 是 4。










