ETag可使90%以上轮询请求返回304,不传响应体;需服务端基于更新时间戳生成ETag、客户端自动携带If-None-Match,并配合Cache-Control: no-cache;对高实时低频变更数据应改用WebSocket主动推送。

页面大量轮询接口会持续消耗网关连接、带宽和后端资源,尤其在低频变化但高频请求场景下,浪费尤为明显。用 ETag 做条件验证或切换为 WebSockets,并非二选一,而是按数据更新特征分层应对。
用 ETag 减少无效响应体传输
轮询接口若返回的是相对静态、变更不频繁的数据(如配置项、用户权限、状态摘要),ETag 可让 90% 以上请求只返回 304,不传 Body。
- 服务端生成 ETag 应基于内容实际变更依据,优先用数据库记录的 更新时间戳或版本号,而非完整响应体哈希——避免每次请求都做序列化+哈希计算
- 响应头中必须设置 Cache-Control: no-cache(允许缓存但强制校验),同时带上 ETag;客户端轮询时自动携带 If-None-Match
- 前端轮询逻辑无需改造,只需确保 fetch 或 axios 请求默认启用缓存协商(现代浏览器默认支持)
- 注意:ETag 对同一 URL 有效,若轮询带动态 query(如 timestamp=xxx),需统一移除或标准化参数,否则缓存失效
对高实时性、低频变更数据改用 WebSockets
当轮询目标是状态类数据(如任务进度、审批结果、消息通知),且变更间隔远大于轮询间隔(例如每分钟变一次,却每 2 秒轮询),WebSockets 能彻底消除空轮询。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 服务端维护轻量级连接状态,仅在数据真正变更时推送一次消息,而不是被动响应千次请求
- 前端建立单个长连接,用 message 事件监听,替代 setInterval + fetch 组合;连接断开后自动重连(建议指数退避)
- 网关需支持 WebSocket 协议升级(如 Nginx 配置 proxy_http_version 1.1 和 Upgrade/Connection 头),并合理设置 idle timeout
- 不建议全量替换:WebSocket 更适合“推”,而轮询仍适用于权限校验、登录态续期等需主动发起的控制类请求
混合策略:按数据语义分级处理
一个页面常含多种轮询需求,可拆解归类,分别优化:
- 配置型数据(如系统开关、文案配置):设长缓存(Cache-Control: public, max-age=3600)+ ETag,1 小时内几乎零请求体传输
- 状态摘要型(如待办数量、未读消息数):短周期轮询(如 30s)+ ETag,多数返回 304
- 事件驱动型(如工单分配、审批通过):关闭轮询,由后端通过 WebSocket 主动推送 JSON 消息,前端局部更新 DOM
- 所有轮询接口应加统一请求标识(如 X-Request-Source: polling),便于网关层识别并限流、监控异常高频行为
验证是否生效的关键指标
优化不是调完就结束,要盯住真实链路数据:
- 网关层:对比优化前后,HTTP 200 响应占比下降、304 响应占比上升;WebSocket 连接数稳定,消息推送量远低于原轮询请求数
- 后端服务:CPU 使用率下降(尤其减少 JSON 序列化与 DB 查询)、慢日志中轮询接口耗时分布左移
- 前端:Network 面板中轮询请求的 Size 列大量显示 “from cache” 或 “304”,Timing 中 wait 时间显著缩短


















