包大小优化
概述
更小的包下载更快,解析更快,执行更快,特别是在网络较慢的情况下,显著提高了感知性能。
何时使用
- 构建过程优化
- 部署前的包分析
- 性能基线改进
- 移动性能重点
- 添加新依赖后
指令
1. 包分析
// 分析包组成
class BundleAnalysis {
analyzeBundle() {
return {
tools: [
'webpack-bundle-analyzer',
'Source Map Explorer',
'Bundle Buddy',
'Bundlephobia'
],
metrics: {
total_size: '850KB gzipped',
main_js: '450KB',
main_css: '120KB',
vendor: '250KB',
largest_lib: 'moment.js (67KB)'
},
breakdown: {
react: '85KB (10%)',
lodash: '45KB (5%)',
moment: '67KB (8%)',
other: '653KB (77%)'
}
};
}
identifyOpportunities(bundle) {
const opportunities = [];
// 检查重复依赖
if (bundle.duplicates.length > 0) {
opportunities.push({
issue: '重复依赖',
impact: '可能减少50KB',
solution: '去重包'
});
}
// 检查未使用的包
if (bundle.unused.length > 0) {
opportunities.push({
issue: '未使用的依赖',
impact: '减少100KB',
solution: '移除未使用的包'
});
}
// 检查包大小与目标
if (bundle.gzipped > 250) {
opportunities.push({
issue: '包太大',
impact: '超出目标',
solution: '代码拆分或摇树'
});
}
return opportunities;
}
}
2. 优化技术
代码拆分:
基于路由:按路由拆分(每个路由约50-100KB)
基于组件:拆分大型组件
库拆分:分离供应商包
工具:webpack, 动态导入, React.lazy()
摇树:
移除未使用的导出
在webpack/rollup中启用
与ES模块最搭配
检查:bundle-analyzer显示未使用
压缩:
JavaScript: Terser, esbuild
CSS: cssnano, clean-css
结果:通常减少20-30%
例子:100KB → 70KB
移除依赖:
Moment.js (67KB) → date-fns (13KB)
Lodash (70KB) → lodash-es (30KB, 可以摇树)
旧包检查:npm outdated
动态导入:
import('module') 按需加载
减少初始包
用于:模态框,屏幕外特性
例子:850KB → 400KB初始 + 懒加载
---
包大小目标:
JavaScript:
初始:<150KB gzipped
每路由:<50KB gzipped
总计:<300KB gzipped
CSS:
初始:<50KB gzipped
每页:<20KB gzipped
图片:
总计:<500KB优化
每图片:<100KB
3. 实施策略
优化计划:
第1周:分析与快速胜利
- 运行包分析器
- 移除未使用的依赖
- 更新大型库
- 启用摇树
- 预期:减少20%
第2周:代码拆分
- 实施基于路由的拆分
- 延迟加载重型组件
- 分割供应商包
- 预期:从初始减少40%
第3周:高级优化
- 移除未使用的polyfills
- 升级转译器
- 优化包中的图片
- 预期:总计减少50-60%
---
监控:
设置预算:
- 在CI/CD中跟踪包大小
- 超过阈值时警告
- 每次提交跟踪
- 历史趋势
工具:
- bundlesize npm包
- webpack-bundle-analyzer
- GitHub检查集成
流程:
- 测量前
- 实施变更
- 测量后
- 文档结果
4. 最佳实践
- 定期监控包大小(每次构建)
- 为团队设置严格的包预算
- 使用现代语法(不要为所有浏览器polyfill)
- 偏好轻量级替代重库
- 延迟加载非关键代码
- 保持供应商分开以获得更好的缓存
- 移除未使用的依赖(npm audit)
- 使用生产构建进行测量
- 在真实的3G网络模拟上测试
清单:
- [ ] 安装并配置包分析器
- [ ] 移除未使用的依赖
- [ ] 实施代码拆分
- [ ] 启用摇树
- [ ] 在CI/CD中设置包预算
- [ ] 用轻量级替代品替换大型库
- [ ] 为大型特性动态导入
- [ ] 分离供应商包
- [ ] 优化资产
- [ ] 建立性能基线
提示
- 首先关注初始包(影响加载时间最多)
- 测量gzip大小(用户接收的内容)
- 摇树与ES模块最搭配
- 大多数库都有轻量级替代品
- 使用webpack/vite内置分析工具