HTML中script和link加载顺序影响请求数:script默认同步阻塞,link stylesheet并行请求;同域同类型无动态依赖的JS/CSS可安全合并,但async/defer脚本、preload链接及动态导入不可合并;构建工具如Webpack、Vite更可靠;HTTP/2下首屏关键资源应≤3个,内联仅适用于

HTML 中 script 和 link 标签的加载顺序直接影响请求数
浏览器解析 HTML 时, 默认同步阻塞,每个 src 都触发一次 HTTP 请求; 虽不阻塞 HTML 解析,但多个 CSS 文件仍会并行发起多次请求。关键不是“能不能合并”,而是“哪些能安全合并”。
- 同域、同类型(如都是
text/css或都是module)、无动态document.write依赖的 JS/CSS 可物理合并 - 带
async或defer的不建议与同步脚本合并,否则可能破坏执行时序 -
单独保留,它本身不加载资源,只是提示预加载,不能合并进其他文件
用构建工具做静态资源合并比手写更可靠
手动拼接 main.js + utils.js + vendor.js 容易漏掉 export/import 冲突或全局变量覆盖。现代打包器能自动处理模块依赖图、作用域隔离和 tree-shaking。
- Webpack:配置
optimization.splitChunks.chunks: 'all'控制代码分割粒度,设为false可强制单入口输出一个bundle.js - Vite:默认不合并,但可通过
build.rollupOptions.output.manualChunks显式指定哪些包打进同一 chunk - 注意:
import('./dynamic.js')这类动态导入仍会生成独立 chunk,不会被合并,这是预期行为
HTTP/2 下多小文件不一定比大文件慢,但首屏仍要控制关键资源数
HTTP/2 支持多路复用,10 个 5KB 的 JS 文件在同一个连接上传输,并不比 1 个 50KB 文件慢多少——但前提是 TLS 握手已完成、连接已复用。首次访问时,过多 仍会触发多个 HEAD 或 GET 请求,增加队头阻塞风险。
- 首屏必需资源(如渲染关键 CSS、核心 JS)应 ≤ 3 个请求,优先内联或合并
- 非关键资源(如统计脚本、埋点 SDK)用
loading="lazy"(图片)或fetch().then()(JS)延迟加载 - 检查 Chrome DevTools 的
Network → Priority列,确认high优先级资源没被拆得太碎
内联关键 CSS/JS 有收益也有代价,别无脑塞进
内联可消除请求,但会增大 HTML 体积、阻碍缓存复用。仅当 CSS/JS 小于 ~2KB 且只用于当前页面时才考虑内联。
立即学习“前端免费学习笔记(深入)”;
- 内联前先压缩:用
csso处理 CSS,terser压缩 JS,避免把未压缩内容直接贴进 HTML - 服务端渲染(SSR)场景下,内联 CSS 必须与组件实际样式严格对应,否则 hydration 时 React/Vue 会警告
Prop `className` did not match - 不要内联含
document.write、eval或依赖window的脚本——它们在 HTML 解析阶段尚未就绪
真正难的不是“怎么合并”,是判断哪些资源该合并、哪些该拆、哪些该延迟——这取决于你的首屏渲染路径、缓存策略和部署方式。一个被 gzip 压缩后 80KB 的 JS bundle,在 HTTP/2 + 浏览器强缓存下,可能比 5 个 15KB 的文件更慢,因为后者可并行解析执行。










