Skip to content
⚠️ This article was written in 2018. Some content may be outdated.

webpack-bundle-analyzer: Bundle Analysis in Practice

You finish a build and find vendor.js is 3 MB and loading slowly, but you have no idea which libraries are taking up the most space. webpack-bundle-analyzer is the standard tool for this problem.

Installation and Configuration ​

bash
npm install --save-dev webpack-bundle-analyzer
javascript
// webpack.config.js
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: "server", // starts an analysis server, default port 8888
      openAnalyzer: true, // automatically opens the browser
      // analyzerMode: 'static', // generate a static HTML report
      // reportFilename: 'report.html'
    }),
  ],
};

To avoid affecting regular development, only enable it when needed:

json
{
  "scripts": {
    "build": "webpack --mode production",
    "analyze": "ANALYZE=true webpack --mode production"
  }
}
javascript
// webpack.config.js
const analyze = process.env.ANALYZE;

module.exports = {
  plugins: [analyze && new BundleAnalyzerPlugin()].filter(Boolean),
};

Reading the Analysis Report ​

The report opens as a treemap:

  • Area = file size (before gzip)
  • Color depth = number of contained modules
  • Clickable to expand = view the specific modules included

Key things to look for:

  1. Which libraries in node_modules are the largest
  2. Whether any modules are bundled multiple times
  3. Whether any of your own business code is unexpectedly large

Common Optimization Targets ​

1. Entire lodash Being Bundled ​

javascript
// ❌ This bundles the entire lodash (71KB gzipped)
import _ from "lodash";
const result = _.chunk([1, 2, 3, 4], 2);

// ✅ Import only the functions you need (individual lodash functions are a few KB each)
import chunk from "lodash/chunk";
const result = chunk([1, 2, 3, 4], 2);

// Or install lodash-es (tree-shaking friendly)
import { chunk } from "lodash-es";

2. moment.js Locale Files ​

moment.js bundles all locale files by default (~160KB). Most projects only use a couple of locales:

javascript
// webpack.config.js
const webpack = require("webpack");

module.exports = {
  plugins: [
    // Keep only Chinese and English
    new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn|en/),
  ],
};

Or switch to day.js outright (only 2KB, mostly API-compatible).

3. Element UI On-Demand Loading ​

bash
npm install babel-plugin-component
json
// .babelrc
{
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}
javascript
// ❌ Full import (~500KB)
import ElementUI from "element-ui";
Vue.use(ElementUI);

// ✅ On-demand import (only bundles the components you use)
import { Button, Table, Form, Input } from "element-ui";
Vue.use(Button);
Vue.use(Table);

4. Route Lazy Loading ​

javascript
// ❌ Everything bundled into the main bundle
import HomePage from "@/pages/HomePage";
import AboutPage from "@/pages/AboutPage";

// ✅ Load on demand
const HomePage = () => import("@/pages/HomePage");
const AboutPage = () => import("@/pages/AboutPage");

// Group related routes into one chunk
const UserProfile = () =>
  import(/* webpackChunkName: "user" */ "@/pages/UserProfile");
const UserSettings = () =>
  import(/* webpackChunkName: "user" */ "@/pages/UserSettings");
javascript
// webpack.config.js
module.exports = {
  externals: {
    vue: "Vue",
    "element-ui": "ELEMENT",
    echarts: "echarts",
  },
};
html
<!-- index.html - load from CDN -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui@2.4.11/lib/index.js"></script>

A Real Optimization Record ​

OptimizationBeforeAfter
Full lodash → on-demand71KB3KB
Full moment → day.js230KB2KB
Element UI on-demand loading500KB200KB
Route lazy loadingAll upfrontOn demand
Total size1.8MB680KB

After gzip, size is reduced by another ~70%. Final first-screen JS dropped from 540KB to ~200KB.

Summary ​

  • Use webpack-bundle-analyzer to visualize and find problems first
  • lodash and moment are common size culprits — address them specifically
  • UI library on-demand loading delivers significant gains
  • Route lazy loading greatly improves the first-screen experience
  • Don't optimize blindly — measure first, then act

MIT Licensed