HTTP/2推送需确保CSS优先于图片:Nginx按http2_push声明顺序推送,应先配置CSS再图片;配合Link头指定as=style/image强化浏览器优先级;严格限制推送范围,仅关键资源,并通过Chrome DevTools和curl验证。

HTTP/2 的 http2_push 能主动推送关键资源,但默认不区分优先级——CSS 本该比图片更早到达,却可能被一同推送、甚至因队头阻塞或权重设置不当而延迟解析。Nginx 本身不支持为单个 http2_push 指令设置独立权重或依赖关系,但可通过资源加载顺序、响应头控制与配置组合,实现事实上的优先级调度。
明确推送顺序:CSS 必须在 HTML 响应中首个声明
Nginx 的 http2_push 按配置顺序触发,浏览器也按推送流的接收顺序处理依赖。把 CSS 放在所有图片之前推送,能确保渲染引擎尽早拿到样式规则:
- 在
location块中,先写http2_push /style.css;,再写http2_push /logo.png;、http2_push /banner.jpg; - 避免在同一个 location 中混用高/低优先级资源;可拆分为多个 location(如
/app/推送 CSS + JS,/img/推送图片),再通过try_files或 rewrite 统一处理 - 验证方式:Chrome DevTools → Network → 启用 “Waterfall” 视图,观察 Push 列中 CSS 流的 Start Time 是否明显早于图片
配合 Link 头强化语义与浏览器调度
仅靠 http2_push 不足以让浏览器理解资源依赖层级。需手动添加 Link 响应头,标明 preload 和 as 类型,帮助浏览器正确排序解码与加载优先级:
- 对 CSS:添加
Link: </style.css>; rel=preload; as=style—— 浏览器会将其加入高优先级 preload 队列,立即解析 - 对图片:使用
as=image,但避免对非首屏图片(如懒加载图)启用 push + preload,否则挤占带宽 - Nginx 配置示例:
add_header Link '</style.css>; rel=preload; as=style, </logo.png>; rel=preload; as=image';
限制推送范围,避免干扰关键路径
盲目推送所有关联资源会引发流竞争,尤其当图片体积大、数量多时,反而拖慢 CSS 解析。应严格限定推送集合:
立即学习“前端免费学习笔记(深入)”;
- 只推送 HTML 中
<link rel="stylesheet">和内联<script>引用的资源,不推送<img src>中的图片(除非是 LCP 图片且已确认为关键) - 用
map指令按 URI 动态控制推送列表:
map $request_uri $push_resources {<br> ~^/home\.html " /style.css; /main.js; /hero.jpg";<br> ~^/article\.html " /style.css; /article.css";<br> default "";<br> }
再在 location 中写:http2_push $push_resources; - 禁用对 304/206 响应的推送(加
http2_push_preload off;可防止重复推送)
验证与调优:用 curl 和浏览器双轨检测
真正生效需两端协同:Nginx 正确发起 PUSH_STREAM,浏览器正确调度。不要只看 Nginx 日志:
- curl 查协议层:
curl -I --http2 -v https://yoursite.com/home.html 2>&1 | grep "PUSH_PROMISE",确认 CSS 的 PUSH_PROMISE 出现在图片之前 - Chrome 中打开
chrome://net-internals/#http2,筛选对应域名,查看 PUSH_STREAM 条目中的 Priority 字段(虽 Nginx 不设 weight,但浏览器会根据as类型自动分配权重,style 默认高于 image) - 对比开启/关闭 push 后的 FCP(First Contentful Paint) 和 Speed Index,若提升不明显,大概率是推送了非关键资源或带宽被图片抢占
不复杂但容易忽略:HTTP/2 推送不是“越多越好”,而是“CSS 必先到、图片慎选推、Link 头来补位”。Nginx 提供的是通道,优先级靠设计和协同落地。

















