Analyze bundle size with BundleAnalyzerPlugin
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 behaviorserver
: Launches an HTTP server to display the report (default)static
: Generates a single-page HTML filejson
: Generates a JSON format reportdisabled
: Disables the plugin
-
analyzerHost
: Specifies the server host address, default127.0.0.1
-
analyzerPort
: Specifies the server port, default8888
-
reportFilename
: Static report filename, defaultreport.html
-
defaultSizes
: How module sizes are displayedstat
: Original file sizeparsed
: Processed size (default)gzip
: Size after gzip compression
-
openAnalyzer
: Whether to automatically open the browser, defaulttrue
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
- Pay special attention to individual modules exceeding 200KB
- Repeated occurrences of the same module
- Duplicate imports of third-party libraries in multiple chunks
- 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
下一篇:自定义Plugin开发实践