HTTP/2 Server Push 在 Nginx 中已不可用,因Chrome 96+、Firefox 97+等主流浏览器自2021年起弃用PUSH_PROMISE帧,Nginx 1.24.x/1.26.x稳定版默认不支持http2_push;应改用Link: ; rel=preload响应头实现兼容性预加载。

HTTP/2 Server Push 在 Nginx 中已不可用,配了 http2_push 也不会触发真实推送——不是你配置错了,是协议和浏览器都已废弃它。
Chrome、Firefox、Edge 都已禁用 PUSH_PROMISE 帧
自 2021 年起,主流浏览器陆续移除对 Server Push 的支持:Chrome 96+、Firefox 97+、Edge 96+ 全部静默丢弃 PUSH_PROMISE。你在 DevTools Network 面板里再也看不到 Initiator 列标为 Push 的请求;chrome://net-internals/#http2 中即使看到 PUSH_PROMISE 日志,对应 stream 状态也多是 Abandoned。
这意味着:
-
http2_push /style.css;这类配置在 Nginx 1.24.x / 1.26.x 等当前稳定版中,实际是服务端单向发送、客户端直接忽略 -
http2_push_preload on;依赖响应头中的Link,但浏览器只按rel=preload处理,不走 Push 通道 -
http2_push_limit或http2_push_priority等指令虽存在,但因底层推送机制失效,基本无实际效果
Nginx 不推 CSS,但可以可靠预加载 CSS
真正有效、标准、兼容 HTTP/1.1 和 HTTP/2 的方式,是使用 Link 响应头声明 rel=preload:
立即学习“前端免费学习笔记(深入)”;
- 路径必须是绝对 URI(以
/开头),例如/css/app.css,不能带查询参数(/style.css?v=1会被丢弃) -
as属性必须准确,CSS 用as=style,JS 用as=script,字体用as=font - 该头默认透传,Nginx 无需额外模块,直接在
location = /index.html或根location /块中加即可
示例配置:
location = /index.html {
add_header Link '</css/app.css>; rel=preload; as=style', '</js/runtime.js>; rel=preload; as=script';
}
宝塔面板或手动配置时的三个关键动作
如果你正在用宝塔或直接编辑 Nginx 配置文件,请确认这三件事:
- SSL 已启用,且
listen行包含http2(如listen 443 ssl http2;) -
add_header Link放在具体的location块内(比如匹配 HTML 的 location),**不要放在server全局块**,否则会误加到图片、API 等响应上 - 重载配置后,用 Chrome DevTools → Network → Headers 查看 HTML 响应中是否有
link:字段,并检查 CSS 请求的 Initiator 是否为preload
别把预加载当推送,更别盲目加资源
真正影响首屏性能的,不是“推不推”,而是“推不推得对”:
- 已带
Cache-Control: immutable或强缓存的 CSS,重复preload是冗余请求 - 体积大的 CSS(>100KB)或非首屏样式,预加载反而挤占带宽
- 字体文件仅在明确用于首屏且是
.woff2时才考虑加as=font;图片、视频一律跳过
现代优化的关键,是让应用层(PHP/Node.js)动态生成 Link 头,而非靠 Nginx 硬编码推送——因为只有业务逻辑清楚哪些 CSS 此次渲染真正需要。


















