HTTP/2 Server Push vs 103 Early Hints:谁是CDN加速的更好选择?

HTTP/2 Server Push曾被视为提升页面加载速度的利器,但如今已被淘汰;而103 Early Hints正成为CDN边缘节点加速的新标准。本文面向小白,用通俗的语言解释两者的原理、对比性能差异,并给出实际配置建议。

HTTP/2 Server Push vs 103 Early Hints:谁是CDN加速的更好选择?
封面图:ZuCDN · ZuCDN 原创

如果你正在处理CDN HTTP,先别急着照搬网上的参数。当你打开一个网页时,浏览器需要先获取HTML,然后解析出CSS、JavaScript、图片等资源,再逐一请求。这个过程叫“瀑布流”,其中每一轮往返都会增加延迟——尤其是在CDN边缘节点离用户很近但仍需多次握手的场景下。为了进一步提速,工程师们提出了两种思路:让服务器在返回HTML之前就主动把资源推送给客户端(HTTP/2 Server Push),或者提前告诉客户端“你接下来可能需要这些资源,先去准备”(103 Early Hints)。

这两种技术听起来很像,但实际效果和命运截然不同。本文从零开始,带你搞懂它们是什么、为什么一个被放弃、另一个被推崇,以及你的CDN应该如何利用它们。

CDN HTTP:HTTP/2 Server Push:主动推送的美好想象

验证与回滚

HTTP/2 Server Push 是HTTP/2协议引入的一项特性。它的核心思想是:当服务器发送HTML响应时,可以“顺手”把HTML里引用的关键资源(比如style.css、app.js)一并推送给客户端,而不需要等待客户端解析HTML后再发出请求。这样一来,浏览器收到HTML时,这些资源已经在缓存里了,加载时间大幅缩短。

听起来很完美,对吗?

但现实中有几个很头疼的问题:

  • 带宽浪费:服务器并不清楚客户端是否已经缓存了这些资源。如果用户第二次访问,浏览器本地已有该CSS文件,但服务器仍然强行推送,就会浪费带宽,甚至让原本可以用的缓存失效。
  • 优先级混乱:浏览器有自己的一套资源加载优先级(比如关键CSS优先、图片延迟加载)。但Server Push由服务器决定,很容易推送非关键的资源,反而阻塞了真正需要的请求。
  • 连接竞争:推送的资源流与浏览器主动发起的请求共享同一个TCP连接,可能导致队头阻塞。
  • 实现复杂:中间代理、CDN边缘节点需要对推送流做特殊处理,很多旧设备或软件不支持甚至直接忽略。

由于这些痛点,Chrome团队早在2021年就宣布默认禁用HTTP/2 Server Push,并推动用更优雅的方案替代——也就是我们今天的主角之一:103 Early Hints。

103 Early Hints:给浏览器一个“小抄”

故障定位思路

103 Early Hints 是一种HTTP状态码,但和常见的200、404不同,它不会替代最终的响应。它的工作流程如下:

  1. 浏览器向CDN边缘节点请求一个页面(例如 GET /index.html)。
  2. 服务器在正式返回200 OK之前,先发送一个103 Early Hints响应,里面包含一个 Link 头,告诉浏览器:“这个页面最终会用到 style.css 和 app.js,你可以现在就去预加载它们。”
  3. 浏览器收到103后,会立即根据 Link 头中的提示,开始预连接或预加载这些资源(通过 preloadpreconnect 等机制)。
  4. 服务器随后发送真正的200响应(包含完整的HTML),浏览器此时已经获取了一部分资源,甚至可能已经完成加载。

与Server Push最大的区别是:Early Hints只是“建议”,不是“强制”。浏览器可以自行判断是否真的需要这些资源:如果本地缓存已经有了,直接忽略提示;如果网络条件差,可以延迟执行。同时,Early Hints占用的头部非常小,几乎不消耗额外带宽。

性能对比:为什么103 Early Hints更优?

我们可以从几个维度来对比这两种技术在实际CDN环境中的表现:

1. 带宽利用率

  • Server Push:资源直接推送,无法感知客户端缓存。浪费带宽比例可达30%-50%(根据Google的实测)。
  • 103 Early Hints:只发送一个很小的HTTP头(几十字节),不推送实际资源。浏览器根据需要决定是否请求,基本无浪费。

2. 控制粒度

  • Server Push:推送逻辑完全由服务器/CDN边缘节点控制,无法动态适应不同用户的网络和设备。
  • 103 Early Hints:浏览器掌握最终决策权。CDN只需要告诉浏览器“有哪些可能需要的资源”,浏览器结合自己的缓存、优先级、用户设置来执行,更智能。

3. 兼容性

  • Server Push:只能在HTTP/2连接上生效,HTTP/1.1不支持。很多代理、防火墙会丢弃推送流,导致部分用户收不到。
  • 103 Early Hints:在HTTP/1.1、HTTP/2和HTTP/3中均可使用(HTTP/1.1下作为拓展状态码,大多数现代服务器和CDN已支持)。兼容性更好,迁移成本低。

4. 对首字节时间(TTFB)的影响

  • Server Push:需要在发送HTML之前先推送资源,可能会延迟HTML的传输,导致首字节时间变慢。
  • 103 Early Hints:103响应极其轻量,几乎不增加TTFB,同时使得后续资源请求可以提前开始,从而显著缩短关键渲染路径。

根据公开的测试数据(如Cloudflare、Akamai的实践),启用103 Early Hints后,页面加载时间(尤其是LCP)平均可减少10%-30%,而Server Push带来的收益却极不稳定,甚至有时会适得其反。

CDN边缘节点如何配置103 Early Hints?——CDN HTTP

故障定位思路

对于使用CDN的小白用户,配置103 Early Hints通常不需要修改你的源站代码。大多数主流CDN服务商(如Cloudflare、Akamai、Fastly、以及国内的一些CDN厂商)已经原生支持。你只需要在控制台开启一个开关,或者添加一个自定义响应头。

例如,在Cloudflare的“速度”选项卡下,找到“Early Hints”并开启即可。对于自建CDN边缘节点(比如基于Nginx或Envoy),可以通过配置Lua脚本或使用第三方模块实现。关键代码思路是在返回200之前,先判断请求是否为HTML页面,然后生成一个包含 Link 头的103响应。

# Nginx + Lua 示例(仅示意)
location / {
    early_hints on;
    set $early_hints_link '</style.css>; rel=preload; as=style, </app.js>; rel=preload; as=script';
    add_header Link $early_hints_link always;
    # 这里需要配合ngx_http_early_hints_module
}

注意:不要随意复制上面的代码到生产环境,具体实现请参考CDN厂商文档。核心是:你需要在边缘节点识别出哪些资源是“首屏关键资源”,然后将其URL放到 Link 头中。

实战建议:该放弃Server Push了吗?

先看关键判断

如果你正在使用HTTP/2 Server Push,建议尽快迁移到103 Early Hints。理由如下:

  • Chrome已经移除对Server Push的默认支持,未来其他浏览器可能也会跟进。
  • Early Hints已经成为IETF标准RFC 8297,且被各大浏览器支持(Chrome 103+、Edge、Firefox等)。
  • CDN边缘节点部署Early Hints的收益更稳定,风险更低。

对于完全的小白:如果你只是使用CDN加速静态网站,通常什么都不用做——大多数CDN会自动为你应用一些优化。但如果你想进一步榨干性能,可以关注控制台中的“Early Hints”开关或“资源提示”设置。

此外,不要忘了配合其他Resource Hints,如 preconnectprefetch,它们和103 Early Hints可以协同工作。例如,在HTML的 <head> 中使用 <link rel="preconnect" href="https://api.example.com">,可以让浏览器尽早建立连接。而103 Early Hints能让这种提示提前到请求HTML之前,效果叠加。

总结

先看关键判断

HTTP/2 Server Push的设想很美好,但实际落地中暴露了太多问题——带宽浪费、缓存冲突、实现复杂。而103 Early Hints以一种轻量、灵活的方式,实现了类似的加速目标,却没有那些副作用。对于CDN边缘节点而言,Early Hints是当前更优的选择,也是未来性能优化的方向。

记住:技术不是越“主动”越好,给浏览器留出判断空间,往往能获得更好的结果。如果你正在搭建或优化一个CDN加速的网站,不妨从启用103 Early Hints开始,效果可能超乎你的想象。后续只要定期检查关键指标,CDN HTTP就不会变成维护负担。

延伸阅读