HTTP/2 Server Push 已被 Chrome 96+、Firefox 90+、Edge 100+ 彻底弃用,仅能通过 Link: rel=preload; as=style; nopush 预加载资源,关键 CSS 应内联以保障首屏零延迟渲染。

HTTP/2服务端推送(Server Push)已不可靠,现代浏览器(Chrome 96+、Firefox 90+、Edge 100+)全部移除了对它的原生支持。你现在配置的 http2_push 或调用 http.Pusher,浏览器大概率会忽略或降级为 Link: rel=preload 处理——这不是真正的推送,而是客户端主动拉取。
为什么 Chrome 等浏览器彻底弃用 Server Push
根本原因在于语义失控和资源浪费:服务器无法准确判断客户端是否已缓存某 CSS、是否匹配媒体查询(如 print)、是否被 JS 动态禁用。盲目推送反而阻塞关键流、挤占带宽、干扰 TCP 拥塞控制。2021 年起,Chrome 开始静默禁用,2026 年已完全移除 PUSH_PROMISE 帧解析逻辑。
- Network 面板中再也看不到
Initiator: Push标识 -
curl -v --http2 https://yoursite.com不会收到PUSH_PROMISE帧 - 即使 Nginx 配置了
http2_push /main.css,响应头里也不会出现link推送字段(除非你手动加)
如何在不依赖 Server Push 的前提下“优雅”加载关键 CSS
核心思路是:放弃“服务器推”,转向“客户端早知道 + 浏览器自主调度”。现代方案只有一条主路径,且必须满足三项硬约束:
- 在返回
text/html的响应头中,仅对该 HTML 响应添加Link头,路径必须是绝对路径(如/static/base.css),不能是相对路径或无协议路径 -
as=style必须显式声明,否则浏览器按fetch处理,不走 CSS 解析流水线(比如不触发样式计算、不参与 FOUC 控制) - 务必加上
nopush,明确告知浏览器“别尝试推送,只预加载”,避免旧服务端逻辑误触发已被废弃的通道
示例 Nginx 配置片段:
location = /index.html {
add_header Link '/base.css>; rel=preload; as=style; nopush';
add_header Link '/theme.css>; rel=preload; as=style; nopush';
# 注意:不要在这里加 http2_push —— 它已失效且可能引发日志警告
}
真正需要内联的 CSS 有哪些
预加载(rel=preload)只是“提前发起请求”,仍需等待网络传输。对首屏渲染阻塞最严重的 CSS,唯一可靠方式仍是内联(inline):
- 所有影响首屏布局与文本渲染的样式(如字体定义、标题/段落排版、按钮基础样式)
- 体积建议控制在 14KB 以内(避免跨 TCP 分片,保障首包到达即开始解析)
- 内联后,记得移除对应
,否则会重复加载 - 剩余非首屏 CSS(如后台管理页、打印样式、暗色模式)才适合通过
rel=preload或常规异步加载
最后提醒一句:如果你还在调试 http2_push 是否生效,或者纠结 Go 的 http.Pusher 为何没反应——不是你的配置错,是整个机制已经被浏览器厂商集体退役。把精力放在精准识别首屏 CSS、合理拆分内联与预加载、验证 as=style 是否出现在 Network 的 Response Headers 里,才是当下真正有效的优化点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











