bundle-size-optimization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Bundle Size Optimization

包体积优化

Overview

概述

Smaller bundles download faster, parse faster, and execute faster, dramatically improving perceived performance especially on slower networks.
更小的包下载、解析和执行速度更快,能显著提升感知性能,尤其是在较慢的网络环境下。

When to Use

适用场景

  • Build process optimization
  • Bundle analysis before deployment
  • Performance baseline improvement
  • Mobile performance focus
  • After adding new dependencies
  • 构建流程优化
  • 部署前的包分析
  • 性能基准提升
  • 移动端性能优化
  • 添加新依赖后

Instructions

操作指南

1. Bundle Analysis

1. 包分析

javascript
// Analyze bundle composition

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 = [];

    // Check for duplicate dependencies
    if (bundle.duplicates.length > 0) {
      opportunities.push({
        issue: 'Duplicate dependencies',
        impact: '50KB reduction possible',
        solution: 'Deduplicate packages'
      });
    }

    // Check for unused packages
    if (bundle.unused.length > 0) {
      opportunities.push({
        issue: 'Unused dependencies',
        impact: '100KB reduction',
        solution: 'Remove unused packages'
      });
    }

    // Check bundle size vs targets
    if (bundle.gzipped > 250) {
      opportunities.push({
        issue: 'Bundle too large',
        impact: 'Exceeds target',
        solution: 'Code splitting or tree shaking'
      });
    }

    return opportunities;
  }
}
javascript
// 分析包组成

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: 'Duplicate dependencies',
        impact: '50KB reduction possible',
        solution: 'Deduplicate packages'
      });
    }

    // 检查未使用的包
    if (bundle.unused.length > 0) {
      opportunities.push({
        issue: 'Unused dependencies',
        impact: '100KB reduction',
        solution: 'Remove unused packages'
      });
    }

    // 检查包大小是否超出目标
    if (bundle.gzipped > 250) {
      opportunities.push({
        issue: 'Bundle too large',
        impact: 'Exceeds target',
        solution: 'Code splitting or tree shaking'
      });
    }

    return opportunities;
  }
}

2. Optimization Techniques

2. 优化技术

yaml
Code Splitting:
  Route-based: Split by route (each route ~50-100KB)
  Component-based: Split large components
  Library splitting: Separate vendor bundles
  Tools: webpack, dynamic imports, React.lazy()

Tree Shaking:
  Remove unused exports
  Enable in webpack/rollup
  Works best with ES modules
  Check: bundle-analyzer shows unused

Minification:
  JavaScript: Terser, esbuild
  CSS: cssnano, clean-css
  Results: 20-30% reduction typical
  Examples: 100KB → 70KB

Remove Dependencies:
  Moment.js (67KB) → date-fns (13KB)
  Lodash (70KB) → lodash-es (30KB, can tree-shake)
  Old packages check: npm outdated

Dynamic Imports:
  import('module') loads on-demand
  Reduces initial bundle
  Used for: Modals, off-screen features
  Example: 850KB → 400KB initial + lazy

---

Bundle Size Targets:

JavaScript:
  Initial: <150KB gzipped
  Per route: <50KB gzipped
  Total: <300KB gzipped

CSS:
  Initial: <50KB gzipped
  Per page: <20KB gzipped

Images:
  Total: <500KB optimized
  Per image: <100KB
yaml
代码分割:
  基于路由: 按路由分割(每个路由约50-100KB)
  基于组件: 分割大型组件
  库分割: 分离第三方依赖包
  工具: webpack, dynamic imports, 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. Implementation Strategy

3. 实施策略

yaml
Optimization Plan:

Week 1: Analysis & Quick Wins
  - Run bundle analyzer
  - Remove unused dependencies
  - Update large libraries
  - Enable tree shaking
  - Expected: 20% reduction

Week 2: Code Splitting
  - Implement route-based splitting
  - Lazy load heavy components
  - Split vendor bundles
  - Expected: 40% reduction from initial

Week 3: Advanced Optimization
  - Remove unused polyfills
  - Upgrade transpiler
  - Optimize images in bundle
  - Expected: 50-60% total reduction

---

Monitoring:

Setup Budget:
  - Track bundle size in CI/CD
  - Alert if exceeds threshold
  - Track per commit
  - Historical trending

Tools:
  - bundlesize npm package
  - webpack-bundle-analyzer
  - GitHub checks integration

Process:
  - Measure before
  - Implement changes
  - Measure after
  - Document findings
yaml
优化计划:

第1周: 分析与快速优化
  - 运行包分析工具
  - 移除未使用的依赖
  - 更新大型库
  - 启用摇树优化
  - 预期: 体积减少20%

第2周: 代码分割
  - 实现基于路由的分割
  - 懒加载重型组件
  - 分离第三方依赖包
  - 预期: 相比初始体积减少40%

第3周: 高级优化
  - 移除未使用的polyfill
  - 升级转译器
  - 优化包中的图片
  - 预期: 总计减少50-60%体积

---

监控:

设置预算:
  - 在CI/CD中跟踪包体积
  - 超出阈值时触发告警
  - 跟踪每次提交的变化
  - 历史趋势分析

工具:
  - bundlesize npm包
  - webpack-bundle-analyzer
  - GitHub检查集成

流程:
  - 优化前测量
  - 实施变更
  - 优化后测量
  - 记录发现

4. Best Practices

4. 最佳实践

  • Monitor bundle size regularly (every build)
  • Set strict bundle budgets for teams
  • Use modern syntax (don't polyfill all browsers)
  • Prefer lighter alternatives to heavy libraries
  • Lazy load non-critical code
  • Keep vendors separate for better caching
  • Remove unused dependencies (npm audit)
  • Use production build for measurements
  • Test on real 3G network simulation
  • 定期监控包体积(每次构建时)
  • 为团队设置严格的包体积预算
  • 使用现代语法(不为所有浏览器添加polyfill)
  • 优先选择轻量替代方案而非重型库
  • 懒加载非关键代码
  • 分离第三方依赖以提升缓存效率
  • 移除未使用的依赖(npm audit)
  • 使用生产构建进行测量
  • 在真实3G网络模拟环境中测试

Checklist

检查清单

  • Bundle analyzer installed and configured
  • Unused dependencies removed
  • Code splitting implemented
  • Tree shaking enabled
  • Bundle budget set in CI/CD
  • Large libraries replaced with lighter alternatives
  • Dynamic imports for large features
  • Vendor bundles separated
  • Assets optimized
  • Performance baseline established
  • 已安装并配置包分析工具
  • 已移除未使用的依赖
  • 已实现代码分割
  • 已启用摇树优化
  • 已在CI/CD中设置包体积预算
  • 已用轻量替代方案替换大型库
  • 已为大型功能使用动态导入
  • 已分离第三方依赖包
  • 已优化资源
  • 已建立性能基准

Tips

提示

  • Focus on initial bundle first (affects load time most)
  • Measure gzipped size (what users receive)
  • Tree shaking works best with ES modules only
  • Most libraries have lighter alternatives
  • Use webpack/vite analyze tools built-in
  • 优先关注初始包体积(对加载时间影响最大)
  • 测量gzip压缩后的体积(用户实际接收的大小)
  • 摇树优化仅对ES模块效果最佳
  • 大多数库都有轻量替代方案
  • 使用webpack/vite内置的分析工具