多个CSS文件拖慢首屏,因浏览器解析HTML时遇link rel="stylesheet"即暂停,且每个link触发独立HTTP请求,受同域并发限制;小文件多导致排队久,弱网下12个50KB请求可能比1个60KB慢3倍以上。

为什么多个会拖慢首屏
浏览器遇到第一个 <link rel="stylesheet"> 就暂停 HTML 解析,直到该 CSS 下载、解析完成;每个 <link> 都触发一次独立 HTTP 请求,受同域并发限制(HTTP/1.1 通常 6 个),小文件多反而排队更久。哪怕总大小才 50KB,12 个请求在弱网下可能比 1 个 60KB 文件慢 3 倍以上。
构建时合并 CSS 的实操要点
别手动拼接,交给构建工具自动处理:
- Vite 用户:默认已合并,若输出仍有多份 CSS,检查是否用了动态
import()加载样式,或配build.rollupOptions.output.manualChunks把node_modules/样式单独抽成vendor.css - Webpack 用户:确保启用
MiniCssExtractPlugin,并在optimization.splitChunks.cacheGroups中显式归并业务 CSS 到同一 chunk,避免被第三方库样式带偏 - 禁用所有
@import:它无法被静态分析,且在 CSS 内部使用会引发额外串行请求,全部改用import语句或<link> - 路径问题必须处理:原
icon.css中的url(../fonts/icon.woff)合并后基准目录变了,要么改用绝对路径url(/fonts/icon.woff),要么用 PostCSS 插件重写
非关键 CSS 必须延迟加载
把不影响首屏渲染的样式(如 print.css、dark-theme.css、弹窗组件样式)从 <head> 移出,改用异步方式:
<link rel="preload" href="modal.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="modal.css"></noscript>
注意:onload 回调里必须立即执行 this.onload=null,否则 Safari 会重复触发;<noscript> 是降级兜底。
立即学习“前端免费学习笔记(深入)”;
更轻量的做法是直接用 media 属性:<link rel="stylesheet" href="print.css" media="print"> —— 它完全不阻塞主页面渲染,且无需 JS 支持。
内联 Critical CSS 的边界在哪
只内联真正首屏用到的规则,不是把整个 main.css 复制进去:
- 体积控制在 14KB 以内(TCP 初始拥塞窗口常见值),超了会分包传输,反而增加 RTT
- 避开
@font-face和 Base64 图片,它们会让内联体积暴涨且无法缓存 - 别在 SSR 每次请求都实时生成 Critical CSS,CPU 白耗;应预生成静态文件,或用
critters插件在构建时提取 - 验证是否生效:打开 DevTools → Coverage 标签,看内联样式是否覆盖了首屏实际渲染所需的选择器
真正难的不是“怎么合”,而是判断哪些样式算“关键”——它依赖视口尺寸、设备类型、甚至用户登录态,自动化提取工具容易漏掉动态插入的 DOM 对应的样式。



















