阿里云主机折上折
  • 微信号
Current Site:Index > Analyze bundle size with BundleAnalyzerPlugin

Analyze bundle size with BundleAnalyzerPlugin

Author:Chuan Chen 阅读数:44251人阅读 分类: 构建工具

The Role of BundleAnalyzerPlugin

BundleAnalyzerPlugin is a visualization analysis tool in webpack used to display the size of each module and their dependency relationships after bundling. It generates an interactive tree diagram that intuitively presents the composition structure of the bundle, helping developers identify and optimize overly large dependencies.

Installation and Basic Configuration

First, install the plugin via npm or yarn:

npm install --save-dev webpack-bundle-analyzer
# or
yarn add --dev webpack-bundle-analyzer

Import and configure the plugin in the webpack configuration file:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'server', // Options: server, static, json, disabled
      generateStatsFile: true,
      statsOptions: { source: false },
      openAnalyzer: true,
    })
  ]
}

Detailed Explanation of Key Configuration Parameters

  • analyzerMode: Controls the analyzer behavior

    • server: Launches an HTTP server to display the report (default)
    • static: Generates a single-page HTML file
    • json: Generates a JSON format report
    • disabled: Disables the plugin
  • analyzerHost: Specifies the server host address, default 127.0.0.1

  • analyzerPort: Specifies the server port, default 8888

  • reportFilename: Static report filename, default report.html

  • defaultSizes: How module sizes are displayed

    • stat: Original file size
    • parsed: Processed size (default)
    • gzip: Size after gzip compression
  • openAnalyzer: Whether to automatically open the browser, default true

Practical Application Scenarios

Identifying Large Dependencies

After running the build, the analyzer will launch a local server and automatically open the browser to display the visualization report. For example, if lodash occupies a significant amount of space:

// Problematic code example
import _ from 'lodash';

// Optimization: Import on demand
import isEmpty from 'lodash/isEmpty';

Analyzing Duplicate Dependencies

When multiple bundles contain the same dependency, the visualization chart will clearly show duplicate modules. For example, if react is included in multiple chunks:

// Webpack configuration optimization example
optimization: {
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all'
      }
    }
  }
}

Checking Code Splitting Effectiveness

Verify if dynamic imports work as expected:

// Dynamic import example
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

// The analyzer will show a separate chunk

Advanced Usage Techniques

Generating Comparative Reports

Generate comparison data by setting different environment configurations:

// package.json
{
  "scripts": {
    "analyze": "webpack --profile --json > stats.json && webpack-bundle-analyzer stats.json"
  }
}

Custom Analysis Logic

Perform in-depth analysis by combining with stats files:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const stats = require('./stats.json');

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin({
      stats,
      analyzerMode: 'static'
    })
  ]
}

CI Environment Integration

Use headless mode in continuous integration environments:

new BundleAnalyzerPlugin({
  analyzerMode: 'static',
  reportFilename: 'bundle-report.html',
  generateStatsFile: true,
  statsFilename: 'bundle-stats.json',
  openAnalyzer: false
})

Common Issue Solutions

Incomplete Chart Display

When the bundle is too large, it may cause rendering issues. Adjust the default limits:

new BundleAnalyzerPlugin({
  analyzerMode: 'server',
  analyzerHost: '0.0.0.0',
  analyzerPort: 8888,
  logLevel: 'info',
  defaultSizes: 'parsed',
  statsOptions: {
    maxModules: 1000 // Increase the module count limit
  }
})

Excluding Specific Modules

Ignore certain modules during analysis:

new BundleAnalyzerPlugin({
  excludeAssets: (assetName) => 
    assetName.includes('.map') || assetName.includes('hot-update')
})

Handling Insufficient Memory

For very large projects, you may need to increase Node's memory limit:

NODE_OPTIONS=--max-old-space-size=4096 npm run build

Integration with Other Tools

Combining with source-map-explorer

npm install --save-dev source-map-explorer
// package.json
{
  "scripts": {
    "analyze": "source-map-explorer dist/*.js",
    "analyze:all": "source-map-explorer dist/*.js dist/*.css"
  }
}

Combining with webpack-bundle-size-analyzer

npm install --save-dev webpack-bundle-size-analyzer
const analyze = require('webpack-bundle-size-analyzer');

// Use in webpack's stats options
stats: {
  children: true,
  chunks: true,
  modules: true,
  reasons: true,
  usedExports: true,
  // Custom stats output
  stats: {
    all: false,
    assets: true,
    excludeAssets: /\.(map|hot-update\.js)$/,
    performance: true,
    timings: true,
    warnings: true,
    errors: true,
    errorDetails: true,
    builtAt: true,
    chunks: true,
    chunkModules: true,
    chunkOrigins: true,
    modules: true,
    moduleTrace: true,
    source: true,
    children: true,
    reasons: true,
    usedExports: true,
    providedExports: true,
    optimizationBailout: true,
    depth: true,
    maxModules: 0,
    cached: true,
    cachedAssets: true,
    runtimeModules: true,
    dependentModules: true,
    groupAssetsByChunk: true,
    groupAssetsByEmitStatus: true,
    groupAssetsByExtension: true,
    groupAssetsByInfo: true,
    groupAssetsByPath: true,
    groupModulesByAttributes: true,
    groupModulesByCacheStatus: true,
    groupModulesByExtension: true,
    groupModulesByLayer: true,
    groupModulesByPath: true,
    groupModulesByType: true,
    logging: 'verbose',
    outputPath: true,
    publicPath: true,
    entrypoints: true,
    chunkGroups: true,
    assetsSort: '!size',
    chunksSort: '!size',
    modulesSort: '!size',
    nestedModules: true,
    ids: true,
    hash: true,
    version: true,
    env: true,
    warningsFilter: /export .* was not found in/,
    performance: true,
    hints: true,
    colors: true,
    preset: 'normal',
    context: path.resolve(__dirname, 'src'),
    // Use analyzer to process stats
    stats: analyze
  }
}

Performance Optimization Practices

Identifying Unused Code

After discovering unused modules via the analyzer, use webpack's sideEffects flag:

// package.json
{
  "sideEffects": [
    "*.css",
    "*.scss"
  ]
}

Optimizing moment.js Timezone Data

const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/
    })
  ]
}

Optimizing antd Component Library

// babel.config.js
module.exports = {
  plugins: [
    ['import', {
      libraryName: 'antd',
      libraryDirectory: 'es',
      style: true
    }]
  ]
}

Visualization Report Interpretation Tips

Color Code Meanings

  • Yellow: Regular JS code
  • Blue: Dependencies in node_modules
  • Green: Asynchronously loaded modules
  • Gray: Modules shared by multiple chunks

Interactive Operation Guide

  • Click on a module to expand and view its sub-dependencies
  • Hover over a module to display detailed information
  • Use the filter in the top-left corner to filter modules by size
  • Toggle between original size/parsed size/gzip size in the top-right corner

Key Metrics to Focus On

  1. Pay special attention to individual modules exceeding 200KB
  2. Repeated occurrences of the same module
  3. Duplicate imports of third-party libraries in multiple chunks
  4. Large components not properly code-split

Automated Analysis Solutions

Integrating into the Build Process

// webpack.config.js
const isProduction = process.env.NODE_ENV === 'production';

const plugins = [
  // Other plugins...
];

if (process.env.ANALYZE) {
  plugins.push(new BundleAnalyzerPlugin());
}

module.exports = {
  // Other configurations...
  plugins
};
ANALYZE=true npm run build

Setting Threshold Alerts

const { execSync } = require('child_process');
const fs = require('fs');

const stats = JSON.parse(fs.readFileSync('stats.json', 'utf8'));
const largeModules = stats.modules
  .filter(m => m.size > 1024 * 100) // Modules larger than 100KB
  .map(m => `${m.name} (${(m.size / 1024).toFixed(2)}KB)`);

if (largeModules.length > 0) {
  console.warn('Large modules detected:\n', largeModules.join('\n '));
  // Set exit code in CI environments
  if (process.env.CI) process.exit(1);
}

Long-Term Monitoring Strategies

Version Comparison Analysis

Save stats files from each build to establish a historical record:

# Build script example
webpack --profile --json > stats-$(date +%Y%m%d).json

Trend Visualization

Use third-party services like BundlePhobia or Packtracker for long-term trend analysis:

// Packtracker integration example
const PacktrackerPlugin = require('@packtracker/webpack-plugin');

module.exports = {
  plugins: [
    new PacktrackerPlugin({
      project_token: 'your-project-token',
      upload: process.env.CI === 'true'
    })
  ]
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.