资源加载过多会导致页面白屏时间变长、首屏渲染延迟、用户交互卡顿,并可能触发浏览器并发连接限制;HTTP/2虽缓解连接数问题,但大体积资源仍拖慢解析与执行。

资源加载过多会导致什么问题
页面白屏时间变长、首屏渲染延迟、用户交互卡顿,甚至触发浏览器并发连接限制(如 Chrome 对同一域名最多 6 个 HTTP/1.1 连接),Network 面板里大量 pending 状态就是典型信号。HTTP/2 虽缓解了连接数问题,但资源体积过大仍会拖慢解析、编译和执行——尤其是 JavaScript 文件未做代码分割时,main.js 动辄几 MB,首屏根本等不及。
HTML 中如何安全合并与内联关键资源
不是所有资源都适合合并,关键要区分“首屏必需”和“异步按需”。
- 中的首屏 CSS 可提取为内联 ,避免阻塞渲染;非关键 CSS 加 media="print" 或用 loadCSS() 异步加载
- 小于 10 KB 的 JS(如初始化逻辑)可内联进 ,但必须加 type="module" 或 defer,否则会阻塞 HTML 解析
- 图片资源优先用 + srcset 做响应式裁剪,而非加载大图后靠 CSS 缩放
- 避免在 里写多个 ,合并为一个带 async 或 defer 的请求更可控
构建阶段怎么自动化压缩与分包
靠手动合并压缩不可持续,必须接入构建工具链。重点不是“压得最狠”,而是“压得合理”。
- 使用 webpack 时,splitChunks 配置要按路由或功能拆分,避免把 lodash 和业务代码全打进 vendor.js
- terser-webpack-plugin 默认已启用,但要注意 compress.drop_console: true 仅在生产环境开启,开发时保留调试信息
- 图片交给 image-minimizer-webpack-plugin,对 .png 用 oxipng,对 .jpg 用 mozjpeg,比单纯改后缀名压缩率高 30%+
- 字体文件慎用 woff2 子集化(fontmin 或 pyftsubset),中文字体即使子集也常超 500 KB,不如按需加载
HTTP/2 和 HTTP/3 下还要不要合并 JS/CSS
HTTP/2 的多路复用确实减少了合并的必要性,但仍有例外:
- iOS Safari 对 HTTP/2 的头部压缩支持不一致,某些版本下过多小文件反而增加 TLS 握手开销
- 构建产物若包含大量 import('./xxx.js') 动态导入,未配置 magicComments 会导致每个 chunk 单独请求,此时合并仍是有效兜底手段
- Service Worker 缓存策略依赖文件粒度,合并后单个大文件更新会导致全部缓存失效,所以更推荐“语义化分包”(如 login.chunk.js、dashboard.chunk.js)而非物理合并
中的首屏 CSS 可提取为内联 ,避免阻塞渲染;非关键 CSS 加 media="print" 或用 loadCSS() 异步加载
- 小于 10 KB 的 JS(如初始化逻辑)可内联进 ,但必须加 type="module" 或 defer,否则会阻塞 HTML 解析
- 图片资源优先用 + srcset 做响应式裁剪,而非加载大图后靠 CSS 缩放
- 避免在 里写多个 ,合并为一个带 async 或 defer 的请求更可控
构建阶段怎么自动化压缩与分包
靠手动合并压缩不可持续,必须接入构建工具链。重点不是“压得最狠”,而是“压得合理”。
- 使用 webpack 时,splitChunks 配置要按路由或功能拆分,避免把 lodash 和业务代码全打进 vendor.js
- terser-webpack-plugin 默认已启用,但要注意 compress.drop_console: true 仅在生产环境开启,开发时保留调试信息
- 图片交给 image-minimizer-webpack-plugin,对 .png 用 oxipng,对 .jpg 用 mozjpeg,比单纯改后缀名压缩率高 30%+
- 字体文件慎用 woff2 子集化(fontmin 或 pyftsubset),中文字体即使子集也常超 500 KB,不如按需加载
HTTP/2 和 HTTP/3 下还要不要合并 JS/CSS
HTTP/2 的多路复用确实减少了合并的必要性,但仍有例外:
- iOS Safari 对 HTTP/2 的头部压缩支持不一致,某些版本下过多小文件反而增加 TLS 握手开销
- 构建产物若包含大量 import('./xxx.js') 动态导入,未配置 magicComments 会导致每个 chunk 单独请求,此时合并仍是有效兜底手段
- Service Worker 缓存策略依赖文件粒度,合并后单个大文件更新会导致全部缓存失效,所以更推荐“语义化分包”(如 login.chunk.js、dashboard.chunk.js)而非物理合并
import('./xxx.js') 动态导入,未配置 magicComments 会导致每个 chunk 单独请求,此时合并仍是有效兜底手段
- Service Worker 缓存策略依赖文件粒度,合并后单个大文件更新会导致全部缓存失效,所以更推荐“语义化分包”(如 login.chunk.js、dashboard.chunk.js)而非物理合并
真正卡顿的往往不是请求数,而是单个资源的解析耗时。检查 Performance 面板里的 Script Evaluation 和 Layout 时间,比盯着 Waterfall 图上那几条线更有价值。











