HTML中script和link加载顺序影响请求数:script默认同步阻塞,link stylesheet并行请求;同域同类型无动态依赖的JS/CSS可安全合并,但async/defer脚本、preload链接及动态导入不可合并;构建工具如Webpack、Vite更可靠;HTTP/2下首屏关键资源应≤3个,内联仅适用于
浏览器解析 HTML 时, 默认同步阻塞,每个 src 都触发一次 HTTP 请求; 虽不阻塞 HTML 解析,但多个 CSS 文件仍会并行发起多次请求。关键不是“能不能合并”,而是“哪些能安全合并”。
text/css 或都是 module)、无动态 document.write 依赖的 JS/CSS 可物理合并async 或 defer 的 不建议与同步脚本合并,否则可能破坏执行时序 单独保留,它本身不加载资源,只是提示预加载,不能合并进其他文件手动拼接 main.js + utils.js + vendor.js 容易漏掉 export/import 冲突或全局变量覆盖。现代打包器能自动处理模块依赖图、作用域隔离和 tree-shaking。
optimization.splitChunks.chunks: 'all' 控制代码分割粒度,设为 false 可强制单入口输出一个 bundle.js
build.rollupOptions.output.manualChunks 显式指定哪些包打进同一 chunkimport('./dynamic.js') 这类动态导入仍会生成独立 chunk,不会被合并,这是预期行为HTTP/2 支持多路复用,10 个 5KB 的 JS 文件在同一个连接上传输,并不比 1 个 50KB 文件慢多少——但前提是 TLS 握手已完成、连接已复用。首次访问时,过多 仍会触发多个 HEAD 或 GET 请求,增加队头阻塞风险。
loading="lazy"(图片)或 fetch().then()(JS)延迟加载Network → Priority 列,确认 high 优先级资源没被拆得太碎
内联可消除请求,但会增大 HTML 体积、阻碍缓存复用。仅当 CSS/JS 小于 ~2KB 且只用于当前页面时才考虑内联。
csso 处理 CSS,terser 压缩 JS,避免把未压缩内容直接贴进 HTMLProp `className` did not match

document.write、eval 或依赖 window 的脚本——它们在 HTML 解析阶段尚未就绪真正难的不是“怎么合并”,是判断哪些资源该合并、哪些该拆、哪些该延迟——这取决于你的首屏渲染路径、缓存策略和部署方式。一个被 gzip 压缩后 80KB 的 JS bundle,在 HTTP/2 + 浏览器强缓存下,可能比 5 个 15KB 的文件更慢,因为后者可并行解析执行。