资源合并与压缩
减少 HTTP 请求数量和资源体积是前端性能优化的重要手段,资源合并与压缩是其中最基础也最有效的措施。
1. 资源合并
1.1 为什么合并
- HTTP/1.1 下,浏览器对同一域名有并发请求限制(约 6~8 个)。
- 请求数过多会导致排队等待,增加加载时间。
- 合并后请求数减少,但文件体积会增大,需要权衡。
1.2 合并方式
| 资源类型 | 合并方式 |
|---|---|
| CSS | 多个 CSS 文件合并为一个 |
| JS | 多个 JS 文件合并为一个 bundle |
| 小图标 | CSS 精灵图、SVG Sprite、字体图标 |
css
/* CSS 精灵图 */
.icon {
background: url('sprite.png') no-repeat;
}
.icon-home { background-position: 0 0; }
.icon-user { background-position: -20px 0; }2. 资源压缩
2.1 HTML 压缩
- 去除空格、换行、注释。
- 使用 html-minifier 等工具。
2.2 CSS 压缩
- 去除空格、注释、换行。
- 合并相同规则、优化颜色值。
- 使用 cssnano、clean-css。
2.3 JS 压缩
- 变量名缩短、去除注释和空格。
- 使用 Terser、UglifyJS。
js
// 压缩前
function add(a, b) {
return a + b;
}
// 压缩后
function add(n,o){return n+o}2.4 图片压缩
- 使用 TinyPNG、Squoosh、imagemin。
- 选择合适的格式:WebP、AVIF。
3. 构建工具中的实践
3.1 Webpack / Vite
js
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all', // 代码分割
},
minimize: true, // 启用压缩
},
};3.2 Gzip / Brotli 服务端压缩
- 服务器开启 Gzip 或 Brotli,进一步减小传输体积。
- Brotli 压缩率通常比 Gzip 高 20%~30%。
nginx
gzip on;
gzip_types text/plain text/css application/javascript application/json;4. 代码分割 Code Splitting
- 按需加载,避免单个 bundle 过大。
- 路由级别拆分、组件级别拆分。
js
// React 路由懒加载
const Home = lazy(() => import('./pages/Home'));5. 合并与压缩的平衡
| 策略 | 优点 | 缺点 |
|---|---|---|
| 全部合并 | 请求数最少 | 单个文件大,缓存命中率低 |
| 全部拆分 | 缓存利用率高 | 请求数多,HTTP/1.1 性能差 |
| 合理拆分 | 兼顾请求数和缓存 | 需要合理设计 |
6. 最佳实践
- 公共库与业务代码分离。
- 按路由/页面拆分代码。
- 开启 Gzip / Brotli。
- 构建时压缩 CSS、JS、HTML。
- 使用 CDN 分发静态资源。