概述
103 Early Hints 允许服务器在最终响应(200/304 等)准备期间提前发送仅包含可行动的 `Link` 响应头,帮助浏览器尽早建立连接与预加载关键资源,从而缩短首屏关键路径。其设计由 RFC 8297 定义,浏览器会在收到 103 后立即处理 `Link: <...>; rel=preload|preconnect` 等提示,但不会渲染页面内容,待最终响应到达后继续正常流程。
机制与用法
- 状态码:`HTTP/1.1 103 Early Hints`,只允许安全的提示型头部,典型为多个 `Link` 头。
- 可用 `rel`:`preload`、`preconnect`、`dns-prefetch` 等;建议优先对关键 JS/CSS/字体与跨源连接进行预热。
- 与优先级协同:
- 传输层:服务器/CDN可为被预加载的资源返回 RFC 9218 `Priority` 响应头(如 `Priority: u=1, i`),与浏览器端元素 `fetchpriority` 属性形成协同。
- 浏览器侧:在 HTML 中对关键资源使用 `fetchpriority="high"`(如 ``)。
- 兼容性与部署:Chromium 系支持,Cloudflare/Fastly/NGINX/Node.js 等已有实践;仅包含 `Link` 等提示型头,不能包含实体正文。
示例:Node.js 发送 Early Hints(Node 18+)
```js
import http from 'node:http'
const server = http.createServer((req, res) => {
res.writeEarlyHints({
link: [
'; rel="preload"; as="style"; crossorigin',
'; rel="preload"; as="script"; crossorigin',
'; rel="preconnect"; crossorigin'
]
})
// 模拟后台渲染/IO耗时
setTimeout(() => {
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end('')
}, 80)
})
server.listen(8080)
```
示例:NGINX 配置(发送 Link 头作为 103 Early Hints)
```nginx
# 需要构建/发行版支持 http early hints 指令
location = / {
add_header Link "/static/app.css; rel=preload; as=style" always;
add_header Link "/static/app.js; rel=preload; as=script" always;
add_header Link "; rel=preconnect" always;
# 启用 Early Hints
http2_push_preload on; # 某些版本中作为预加载/提示的桥接
}
```
工程建议
- 精准选择:仅对首屏关键资源发送 `preload`,避免过度预载导致带宽竞争与缓存污染。
- 端到端协作:
- 浏览器:关键元素设置 `fetchpriority="high"`,非关键资源保持默认或 `low`。
- 服务器/CDN:返回 `Priority` 响应头以表达紧急度与并行度偏好(RFC 9218)。
- 与 HTTP/2 Server Push 的取舍:Early Hints 不传实体、仅给提示,更易维护且与缓存/优先级更好协作,推荐优先考虑。
- 观测验证:通过 `PerformanceObserver` 的 `resource` 条目与 DevTools 网络面板验证预加载是否提前、优先级是否合理。
参考与验证
- RFC 8297 Early Hints:https://www.rfc-editor.org/rfc/rfc8297
- web.dev Early Hints 指南:https://web.dev/articles/early-hints
- Chromium/DevTools 相关说明:https://developer.chrome.com/docs/web-platform/early-hints/
- RFC 9218 HTTP 优先级:https://www.rfc-editor.org/rfc/rfc9218
- Cloudflare Early Hints 文档:https://developers.cloudflare.com/early-hints/
发表评论 取消回复