应控制link数量在3–5个以内,通过构建工具合并CSS并区分critical/non-critical样式,用media或preload实现非阻塞加载,HTTP/2下仍需优化请求粒度。

多个 确实拖慢首屏
浏览器对同一域名的并行 请求有数量限制(通常 6–8 个),且每个 CSS 文件都会触发一次 TCP 连接、DNS 查询(未复用时)和渲染阻塞。哪怕总大小不大,10 个 2KB 的文件,加载耗时可能远超 1 个 20KB 的文件。
关键不是“CSS 大”,而是“请求多 + 阻塞强”。优化方向只有两个:减少请求数、降低阻塞影响。
用构建工具合并 CSS,但别盲目全打成一个
Webpack、Vite、Rollup 都能通过插件(如 mini-css-extract-plugin 或 css-bundle)把多个 .css 文件打包进少数几个输出文件。但要注意:
- 不要把所有 CSS(含第三方库、主题、后台管理样式)全塞进
main.css—— 首屏根本用不到的规则也会强制解析和计算 - 区分
critical(首屏必需)和non-critical(滚动后/交互后才需)样式。前者内联或提前加载,后者延迟或异步加载 - Vite 用户注意:
build.rollupOptions.output.manualChunks可按模块路径拆分,比如把node_modules/单独抽成vendor.css,避免业务 CSS 更新导致缓存失效
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'lodash-es'],
chart: ['echarts'],
}
}
}
}
})
用 media 和 onload 实现非阻塞加载
对非首屏、非关键 CSS(如打印样式、深色主题、弹窗组件样式),可移出阻塞链:
立即学习“前端免费学习笔记(深入)”;
- 用
media="print"加载,浏览器不阻塞渲染,后续 JS 切换media值激活 - 用
rel="preload"+onload动态切换rel:
注意:onload 在 Safari 旧版和部分 iOS WebView 中不触发, 是降级保障;不要对 main.css 这类核心样式这么干,会引发 FOUC。
HTTP/2 或 HTTP/3 下合并收益变小,但仍有价值
HTTP/2 支持多路复用,理论上 10 个 CSS 请求可复用一个 TCP 连接,减少了连接开销。但以下问题依然存在:
- 每个文件仍需独立的 HTTP 头传输(header 开销累积)
- 浏览器仍要逐个解析、构建 CSSOM,无法并行化
- 缓存粒度更粗 —— 一个组件 CSS 改了,整个大包都要重新下载
- 服务端推送(HTTP/2 Push)已基本被主流浏览器弃用,不可依赖
所以即使启用了 HTTP/2,也建议控制 数量在 3–5 个以内,并按功能域切分(如 base.css、layout.css、component.css),而不是回到“一个巨无霸 CSS”老路。










