DEV Community

Tianya School
Tianya School

Posted on

Webpack Bundle Analyzer Deep Analysis and Optimization of Your Bundle

Webpack Bundle Analyzer is a visualization tool that helps you analyze the output files generated by Webpack, identifying which modules consume the most space, enabling targeted optimizations.

Installation

First, install Webpack Bundle Analyzer and Webpack:

npm install webpack webpack-cli --save-dev
npm install webpack-bundle-analyzer --save-dev
Enter fullscreen mode Exit fullscreen mode

Configuring Webpack

Next, configure your Webpack configuration file (webpack.config.js):

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

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      reportFilename: 'report.html',
      openAnalyzer: false, // Do not auto-open browser
    }),
  ],
  // Other configurations...
};
Enter fullscreen mode Exit fullscreen mode

Generating the Analysis Report

Run Webpack to generate the analysis report:

npx webpack --mode production
Enter fullscreen mode Exit fullscreen mode

This creates a report.html file in the dist directory. Open it to view an interactive chart showing your bundle’s size distribution.

Optimization Strategies

To further optimize your bundle, consider the following strategies:

Code Splitting

Use the splitChunks configuration to split large libraries or components into separate chunks, loading them only when needed.

module.exports = {
  // ...
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Tree Shaking

Enable the sideEffects property and ES modules to allow Webpack to remove unused code.

// package.json
{
  "sideEffects": false
}
Enter fullscreen mode Exit fullscreen mode
// Enable ES modules in Webpack config
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.m?js$/,
        resolve: {
          fullySpecified: false,
        },
      },
    ],
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Using Compression Plugins

Use TerserWebpackPlugin or other minification tools to reduce file sizes.

const TerserWebpackPlugin = require('terser-webpack-plugin');

module.exports = {
  // ...
  optimization: {
    minimize: true,
    minimizer: [
      new TerserWebpackPlugin(),
    ],
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Loader Optimization

Select appropriate loaders, such as url-loader or file-loader, for static assets, setting thresholds to avoid unnecessary transformations.

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, // 8KB
              fallback: 'file-loader',
            },
          },
        ],
      },
    ],
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Module Lazy Loading

For large applications, use dynamic imports (import()) to lazy-load modules, loading them only when required.

// Before
import SomeBigComponent from './SomeBigComponent';

// After
const SomeBigComponent = () => import('./SomeBigComponent');
Enter fullscreen mode Exit fullscreen mode

Code Preheating

For frequently used lazy-loaded modules, preheat them to reduce initial load delays.

// Preload component at app startup
import('./SomeBigComponent').then(() => {
  console.log('SomeBigComponent preloaded');
});
Enter fullscreen mode Exit fullscreen mode

Extracting Common Chunks

Use optimization.splitChunks to extract shared libraries into separate chunks.

module.exports = {
  // ...
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial',
        },
        common: {
          name: 'common',
          test: /[\\/]src[\\/]/,
          chunks: 'all',
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Using CDNs for Libraries

For third-party libraries used across all pages, load them from a CDN to reduce server load and initial load time.

<!-- In HTML template -->
<script src="https://cdn.example.com/jquery.min.js"></script>
Enter fullscreen mode Exit fullscreen mode

Image Optimization

Use image-webpack-loader or sharp to compress and optimize images.

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        use: [
          {
            loader: 'image-webpack-loader',
            options: {
              bypassOnDebug: true, // webpack@4 compatibility
              mozjpeg: {
                progressive: true,
                quality: 65,
              },
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: [0.65, 0.9],
                speed: 4,
              },
              gifsicle: {
                interlaced: false,
              },
              webp: {
                quality: 75,
              },
            },
          },
        ],
      },
    ],
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Leveraging Caching

Enable caching to store Webpack compilation results, speeding up subsequent builds.

module.exports = {
  // ...
  cache: {
    type: 'filesystem',
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Avoiding Duplicate Modules

Use Module Federation or externals to prevent duplicating libraries across multiple applications.

Module Federation (Webpack 5+)

// Host App
module.exports = {
  // ...
  experiments: {
    outputModule: true,
  },
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'host_app',
      remotes: {
        remote_app: 'remote_app@http://localhost:3001/remoteEntry.js',
      },
      shared: ['react', 'react-dom'],
    }),
  ],
  // ...
};

// Remote App
module.exports = {
  // ...
  experiments: {
    outputModule: true,
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'remote_app',
      filename: 'remoteEntry.js',
      exposes: {
        './RemoteComponent': './src/RemoteComponent',
      },
    }),
  ],
  // ...
};
Enter fullscreen mode Exit fullscreen mode

externals Configuration

module.exports = {
  // ...
  externals: {
    react: 'React',
    'react-dom': 'ReactDOM',
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

This informs Webpack that these libraries are available globally, avoiding redundant bundling.

Using Source Maps

Enable source maps during development for easier debugging.

module.exports = {
  // ...
  devtool: 'cheap-module-source-map',
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Optimizing Fonts and Icons

Use url-loader or file-loader with a limit parameter to inline or bundle fonts and icons.

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: '[name].[ext]',
              outputPath: 'fonts/',
            },
          },
        ],
      },
    ],
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Avoiding Global Style Pollution

Use CSS Modules or Scoped CSS to limit CSS scope and prevent style conflicts.

// CSS Modules
import styles from './styles.module.css';

// Scoped CSS
<style scoped>
  .myClass { /* ... */ }
</style>
Enter fullscreen mode Exit fullscreen mode

Optimizing HTML Output

Use HtmlWebpackPlugin to generate optimized HTML templates, automatically injecting Webpack’s scripts and styles.

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      inject: 'body', // Inject scripts at the bottom of body
    }),
  ],
  // ...
};
Enter fullscreen mode Exit fullscreen mode

Using Webpack Dev Server

Use Webpack Dev Server in development for hot reloading and rapid iteration.

module.exports = {
  // ...
  devServer: {
    contentBase: './dist',
    hot: true,
  },
  // ...
};
Enter fullscreen mode Exit fullscreen mode

πŸ“˜ *Want to get more practical programming tutorials? *

πŸ‘¨β€πŸ’» If you want to systematically learn front-end, back-end, algorithms, and architecture design, I continue to update content packages on Patreon
🎁 I have compiled a complete series of advanced programming collections on Patreon:

  • Weekly updated technical tutorials and project practice
  • High-quality programming course PDF downloads
  • Front-end / Back-end / Full Stack / Architecture Learning Collection
  • Subscriber Exclusive Communication Group

πŸ‘‰ Click to join and systematically improve development capabilities: patreon.com/tianyaschool

Thank you for your support and attention ❀️

Top comments (0)