http/2卡顿主因是nginx默认http2_max_concurrent_streams=128限制多路复用,需调高至256–1000并验证connection id复用、排查limit_conn/req干扰及stalled集中排队现象。

开启 HTTP/2 后前端仍卡顿,往往不是协议没生效,而是多路复用被“人为限流”——Nginx 默认配置对单连接并发流(max_concurrent_streams)设了保守上限,浏览器发起几十个请求时,超出部分会被挂起等待,造成视觉上的“卡在 loading”。排查要从协议确认、服务端限制、前端调度三方面同步切入。
确认浏览器确实在用 HTTP/2 且复用同一连接
别只看“h2”标识,还要验证是否真共享连接:
- 打开 Chrome DevTools → Network 面板,刷新页面,选中任意两个静态资源(如
main.js和logo.png) - 分别查看它们的 Headers → Protocol 字段:必须都显示
h2 - 再看 Connection ID(在 Chrome 120+ 的 Network → “Protocol”列右键开启):同一域名下的所有请求应有完全相同的 Connection ID
- 若 Protocol 是 h2 但 Connection ID 不同,说明存在子域名分片或证书不一致,触发了多连接,多路复用失效
检查 Nginx 的流级并发限制配置
Nginx 默认 max_concurrent_streams 是 128,对现代页面(尤其含大量图片/字体)常显不足。需主动调高:
- 在
http或server块中显式设置:http2_max_concurrent_streams 256;(建议 256–1000,根据页面资源数调整) - 同时检查是否启用了
http2_max_requests(单连接最大请求数),默认 1000,若设得太低(如 100),连接会频繁重建,破坏复用效果 - 确认未误配
limit_conn或limit_req作用于整个连接或 stream 级别,这类限速会直接阻塞新流创建
观察浏览器网络瀑布图中的“stalled”行为模式
HTTP/2 下的 stalled 不是 DNS 或 TLS 延迟,而是流排队信号:
- 在瀑布图中筛选出状态为 stalled 的请求,看它们是否集中出现在某几个连续时间点
- 若多个请求在相同毫秒级时间点开始 stalled,且持续时间接近(如都卡 80–120ms),大概率是达到
max_concurrent_streams上限后,后续流在内核事件队列中排队 - 对比开启 HTTP/2 前后的 stalled 分布:HTTP/1.1 是分散在多个连接上排队;HTTP/2 是集中在单连接下“批量挂起”
验证 Nginx 是否真正调度了高并发流
光改配置不够,得看运行时行为:
- 启用 Nginx debug 日志(临时):
error_log /var/log/nginx/debug.log debug_http2;
重启后抓取一次页面加载日志,搜索"stream create"和"stream close",确认活跃流数量峰值是否接近你设的上限 - 用
ss -i查看 TCP 连接详情:ss -i src :443 | grep "ino"(Linux),观察ino字段(in-flight frames)和retrans是否异常升高——过高说明流控窗口压得太紧或网络丢包干扰了帧调度 - 检查 Nginx error log 中是否有
"stream is not active"或"frame too large"类警告,这类错误会静默终止流,导致前端重试堆积
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











