必须用构建工具合并CSS/JS,手写link无效;浏览器对每个或均发起独立请求,仅靠手动拼接文件无法解决依赖、作用域、source map等问题。

合并CSS/JS文件必须走构建工具,手写link没用
浏览器看到多个 或 <script src></script> 标签,不管它们在HTML里写得多紧凑,都会发起独立HTTP请求。所谓“合并”,不是把标签堆一起,而是让一个请求返回多个文件的内容。
常见错误是直接复制粘贴所有CSS进一个all.css,再手动改HTML引用——这看似合并了,但漏掉了模块依赖、作用域污染、source map丢失等问题。真正安全的合并必须由构建工具完成:
-
Webpack:启用optimization.splitChunks.chunks: 'all'并设为false可强制单bundle输出;注意import()动态导入仍会生成独立chunk,无法被合并 -
Vite:通过build.rollupOptions.output.manualChunks显式分组,比如把vue、lodash、业务代码分别打进不同chunk,避免全塞进一个大文件 - 纯静态站点没构建流程?那就别硬合——改用CDN上的已打包版本(如
https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.prod.js),至少省去自己维护的麻烦
HTTP/2下合并仍有价值,但重点转向首屏关键资源数
HTTP/2支持多路复用,10个5KB的JS并行传输不比1个50KB慢——但前提是连接已建立、TLS握手已完成。首次访问时,过多 仍触发多个HEAD/GET请求,加剧队头阻塞风险。
所以合并逻辑要变:
- 首屏渲染必需的CSS/JS应控制在≤3个请求内,哪怕HTTP/2也建议内联或强合并
- 非关键资源(如统计脚本、埋点SDK)用
async或defer,且不要和同步脚本合并,否则执行顺序错乱 -
必须单独保留,它只是提示预加载,合并后语义失效
图片类资源合并优先用CSS Sprites或Base64,而非HTTP请求拼接
想减少图片请求数,别指望把多个 src 写进一个 ——浏览器根本不认。可行路径只有两条:
- CSS Sprites:把小图标合成一张图,用
background-image+background-position切出对应区域;适合固定尺寸、不常更新的图标集 - Base64内联:仅适用于压缩后data:image/png;base64,... 嵌入CSS或HTML;体积增大约33%,但免去一次HTTP往返
- WebP + 懒加载组合更实用:现代浏览器都支持WebP,体积比PNG小30%以上;配合
loading="lazy",非首屏图片根本不会触发请求
服务端参与才是真合并,前端静态HTML做不到
所有“合并”本质都是服务端把多个资源内容打包进一次响应体。纯前端HTML+CDN托管,没服务端逻辑或构建介入,就永远只是多个独立请求。
可选方案有:
- Node.js中间层:用
express拦截/bundle.css请求,读取多个CSS文件内容拼接后返回,需自行处理@import解析和source map映射 - CDN规则合并:Cloudflare Workers或阿里云EdgeScript可编写逻辑,在边缘节点动态聚合资源
- Nginx子请求:通过
subrequest指令串行拉取多个后端接口,再合并响应体——但延迟叠加明显,只适合低频、稳定的小资源
真正难的不是怎么合,是怎么拆:合并后一个文件变更,整个缓存失效;HTTP/2下过度合并反而拖慢首屏,而拆太碎又浪费TCP连接。平衡点得看真实LCP、CLS数据,不是拍脑袋定的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











