103 Early Hints
用法
当服务器发送 103 Early Hints 时,客户端会解析其中的 Link 请求头并预取指定的资源。当服务器需要时间来处理请求、之后才能组装最终响应时,这一机制最为有用。在服务器工作期间,客户端可以利用这段时间加载最终页面所需的样式表、图片或脚本。
注意
在最终 HTTP 响应之前,会预先发送多个 103 Early Hints 响应。
提示并非保证
在任何依赖预测的系统中,准确率都会有所波动。当服务器返回 103 Early Hints 建议客户端获取特定资源时,该建议是基于一个合理的假设。只有最终 HTTP 响应才提供权威的 Link 请求头。
提示与最终请求头之间的差异表现为两种情况:最终响应需要提示中未提及的额外资源,或者作为早期提示获取的资源最终并不需要。在后一种情况下,客户端做了额外的无用功,整体事务时间反而增加。
基于早期提示执行的操作是安全的。例如,使用 GET 方法不会改变服务器状态。
SEO 影响
103 Early Hints 是位于最终状态码之前的信息类响应。搜索引擎爬虫处理的是最终响应,而非中间的信息类响应。早期提示带来的性能收益适用于浏览器,而非爬虫。该状态码可安全使用,不会干扰 Google 对页面的处理。
取代服务器推送
103 Early Hints 机制作为使用 rel=preload 的资源提示框架的一部分,被定位为在现代浏览器中取代服务器推送(server push)机制。与服务器推送不同,103 Early Hints 不依赖最终响应,浏览器即可开始获取指定资源。
注意
出于安全考虑,浏览器将 103 Early Hints 的使用限制为仅在 HTTP/2 和 HTTP/3 连接上。
示例
客户端请求一个 index.html 文件,服务器返回三条关于可能需要的资源的提示。由于服务器仍在生成响应,所请求的文件并不在消息体中。客户端开始加载每条 Link 指令所指定的资源。
短暂延迟后,服务器返回最终的 200 响应,连同官方的 Link 指令以及位于消息体中的 index.html。请注意早期提示与最终资源列表之间的差异。
请求
GET /index.html HTTP/1.1
Host: example.com
响应
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </images/logo.svg>; rel=preload; as=image
Link: </videos/instructions_simple.mp4>; rel=preload; as=video
<there is a short pause in the transmission>
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 100
Link: </style.css>; rel=preload; as=style
Link: </images/logo.svg>; rel=preload; as=image
Link: </images/pro_badge.svg>; rel=preload; as=image
Link: </videos/instructions_advanced.mp4>; rel=preload; as=video
<message body will follow>
第一条早期提示资源 style.css 被客户端获取并处理,logo 图片和 instructions_simple.mp4 视频也是如此。样式表和 logo 都可以直接使用。最终响应中的 pro_badge 图片没有出现在提示里,因此客户端在收到最终响应后才获取该资源。
最终 Link 请求头中的 instructions_advanced.mp4 视频与早期提示不同。服务器通过早期提示建议了 instructions_simple.mp4,但这次获取是不必要的。新指定的视频在 index.html 完整渲染之前仍需获取和处理,由于获取了两个视频而非一个,很可能会增加加载时间。
代码参考
.NET
HttpStatusCode.EarlyHints
Rust
http::StatusCode::EARLY_HINTS
Rails
:early_hints
Go
http.StatusEarlyHints
Symfony
Response::HTTP_EARLY_HINTS
Python3.9+
http.HTTPStatus.EARLY_HINTS
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_EARLY_HINTS
Angular
@angular/common/http/HttpStatusCode.EarlyHints