现代浏览器对同域名css并发请求数限制为6~8个(chrome 6,firefox 8),属渲染引擎硬编码策略;http/1.1下按html顺序排队,http/2需服务端真正启用;关键css须内联或合并,非关键css用preload异步加载,cdn分域可扩容连接池但需权衡握手开销。

Chrome/Firefox对同域名并发数确实是6个
现代浏览器对同一域名的 <link rel="stylesheet"> 并发请求数限制在 6~8 个,这是硬编码在渲染引擎里的策略(Chrome 是 6,Firefox 是 8),不是配置项,也无法通过 meta 或 JS 修改。它作用于 TCP 连接层:每个 <link> 都会尝试建立一个新连接,超出限额的请求会在 Network 面板中显示为 stalled 或 queued,起始时间明显错开。
这个限制只针对 HTTP/1.1;HTTP/2 下虽支持多路复用,但前提是服务端真正启用且客户端协商成功(可通过 curl -I https://yoursite.com 检查响应头是否含 http/2)。否则仍退化为 HTTP/1.1 行为。
- 所有同源
<link rel="stylesheet">共享该连接池,包括 CDN 域名如static1.example.com -
@import不计入此限制,但它在 CSS 解析阶段才触发请求,实际是串行阻塞,比排队还慢 -
media="print"的<link>不参与初始并发竞争,可安全堆叠
多个link标签不会自动并行加载关键CSS
即使你写了 5 个 <link rel="stylesheet">,浏览器也不会“聪明地”把它们全塞进前 6 名——它按 HTML 中出现顺序逐个发起请求。第一个遇到的 <link> 会立即阻塞 HTML 解析,后续样式表哪怕体积小、优先级高,也得排队等前面某个完成释放连接。
更麻烦的是依赖链:<link href="a.css"> 后紧跟 <script src="b.js"></script>,浏览器会等 a.css 完全下载+解析完,才开始下载 b.js(规范要求),哪怕 b.js 加了 defer。
- 不要把
<link>和<script></script>紧挨着写在里 - 首屏必需的样式必须合并为单个文件,或直接内联到
<style></style>中 - 非关键 CSS(如后台页、弹窗、打印)改用
<link rel="preload" as="style" onload="this.rel='stylesheet'">异步注入
preload不能绕过并发限制,但能抢占连接池前排
<link rel="preload"> 本身不占并发名额,但它会提前触发 DNS/TCP/TLS 握手,并把资源优先级提到最高。这意味着:如果 6 个连接正被图片、字体占用,preload 的 CSS 仍可能插队挤进前 6,而普通 <link rel="stylesheet"> 只能干等。
但必须配对使用:preload 只下载不应用,漏掉 onload 回调或重复挂载,会导致白屏或样式闪动。
- 务必写
as="style",否则浏览器无法识别资源类型,降级为低优先级 fetch - 不要对同一 URL 多次
preload,Chrome 会警告Resource was preloaded using link preload but not used within a few seconds - 第三方域名(如
fonts.googleapis.com)要配合<link rel="preconnect">提前建连
CDN分域不是万能解,但能立竿见影
把 10 个 CSS 拆到 css1.example.com 和 css2.example.com,相当于给浏览器多开了两组 6 连接池,瞬间释放排队压力。构建工具(Vite/Webpack)可通过 publicPath 或 assetPrefix 自动重写路径,无需手动改 href。
但要注意副作用:每个新域名带来额外 DNS 查询和 TLS 握手开销,若拆得太碎(比如 5 个子域),反而拖慢首屏。推荐最多 2~3 个静态资源子域,且确保它们都启用了 HTTP/2 和 Brotli 压缩。
- 避免把所有 CSS 都扔进同一个子域,又把所有 JS 扔进另一个——这没解决单域名瓶颈
- 相对路径在分域后容易失效,建议统一用绝对路径(
/css/main.css)或构建时重写 - CDN 必须正确识别
contenthash文件名变更,否则缓存不更新,旧 CSS 会持续拖慢首屏
@import 串联、没预连接、没内联,LCP 就不可能达标。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











