摘要

  • RFC 7540允许 HTTP/2 服务器用 PUSH_PROMISE 预告并发送浏览器可能接着请求的资源;客户端可以关闭或拒绝推送。
  • RFC 9113在 2022 年仍保留 Server Push,同时指出缓存状态、内容协商和用户行为会让预测失败。Chrome 106 的移除说明确认浏览器不再接收、保存和使用这些流。

服务器替浏览器猜下一步

浏览器向网站要一页 HTML,服务器知道里面马上会引用样式表。若先把样式表送到浏览器,后者发现引用时就省下一轮请求。这是2015 年 HTTP/2 规范赋予服务器的机会。PUSH_PROMISE 告诉客户端:服务器已经替它拟好一项请求,随后会在另一个流上交付响应。推送必须关联客户端实际发起的请求,还受到安全、缓存和来源权限条件限制。

关键在“替它拟好”。服务器能看到即将发出的页面,却未必知道浏览器本地已有哪个文件,用户接下来会不会离开,或内容协商会选中哪个版本。规范因此留下拒收方式:客户端可以把 SETTINGS_ENABLE_PUSH 设为零,也可以重置不想要的推送流。服务器取得了抢跑的许可,却没有取得替浏览器决定需求的权力。

推送最诱人的地方,也是它的成本来源。抢先发出的文件占用连接容量;如果浏览器已经缓存了它,或者眼下更需要另一项响应,抢跑就成了插队。Web 性能不是“越早发越好”的计时比赛。发错了货,快递员跑得再快也只会挡住门。

标准没有删,理由先写进去了

2022 年六月的 RFC 9113继续为 Server Push 留出完整章节。它仍承认节省往返时间的可能:服务器猜中浏览器将要请求的脚本或样式表,页面或许更快完成。但规范还明确解释了实践难点:正确预测必须考虑缓存、内容协商和用户行为;误判送来的数据可能与更重要的响应争夺带宽,反而拖慢页面。

这份修订规范也保留了客户端关闭推送的设置。RFC 定义的是参与者可以怎样通信,以及如何拒绝。它不能让浏览器产品团队持续承担接收、缓存和调度推送流的工程费用。功能还在标准里,并不保证读者打开网页时会有相应实现。

Chrome 在 2022 年八月说明,它将在 106 版默认关闭 HTTP/2 Server Push;其理由是性能收益难以稳定取得,实际结果有快有慢,部分情形还会倒退。随后的Chrome 106 变更说明更直接:浏览器移除了接收、保存在内存中和使用服务器推送流的能力。标准的章节留着,Chrome 的收件流程却退场了。

规范仍在,收件人已经改道

Chrome 提出的替代方法包括 103 Early Hints 和预加载。移除说明描述了其中的差别:Early Hints 先递提示,由浏览器决定是否立刻请求资源,也能考虑已有缓存。这篇历史的主角仍是被移除的推送响应——服务器提前寄出文件,与服务器提前提醒可能需要文件,是两种不同的工作分配。

2015 年,HTTP/2 给服务器一次抢先交付的机会。2022 年,修订规范承认预测失败会浪费资源;Chrome 随后停止接收。Server Push 的命运说明,协议文本可以保存一个选项,运行中的浏览器则会根据自己的成本判断收不收这件货。