html5源代码发行如何减少请求数_请求合并与资源优化方法【详解】

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 可物理合并
  • asyncdefer 不建议与同步脚本合并,否则可能破坏执行时序
  • 单独保留,它本身不加载资源,只是提示预加载,不能合并进其他文件

用构建工具做静态资源合并比手写更可靠

手动拼接 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 握手已完成、连接已复用。首次访问时,过多 仍会触发多个 HEADGET 请求,增加队头阻塞风险。

  • 首屏必需资源(如渲染关键 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.writeeval 或依赖 window 的脚本——它们在 HTML 解析阶段尚未就绪

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