阿里云主机折上折
  • 微信号
Current Site:Index > Packaging volume optimization solution

Packaging volume optimization solution

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

Bundle Size Optimization Solutions

Webpack bundle size directly impacts page loading speed and user experience. Through reasonable configuration and optimization techniques, the final output size can be effectively reduced to improve application performance.

Analyze Bundle Size

Before optimization, analyze the current bundle results. The webpack-bundle-analyzer plugin provides a visual representation of module sizes:

npm install --save-dev webpack-bundle-analyzer

Webpack configuration:

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

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

After running the build, an interactive chart will be generated, clearly showing the proportion of each module. Another approach is using stats.json:

module.exports = {
  //...
  profile: true,
  stats: {
    chunks: true,
    chunkModules: true,
    chunkOrigins: true
  }
}

Code Splitting

Properly splitting code can significantly reduce initial loading size. Dynamic imports are an effective way to achieve code splitting:

// Static import
import { largeModule } from './largeModule';

// Changed to dynamic import
const getLargeModule = () => import('./largeModule');

Webpack 4+ supports splitChunks configuration for automatic splitting of common dependencies:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
}

Tree Shaking

Removing unused code effectively reduces bundle size. The ES6 module system supports static analysis:

// math.js
export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}

// app.js
import { cube } from './math.js';
// square will be removed as it's unused

Ensure the configuration supports Tree Shaking:

module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
    minimize: true
  }
}

Note: When using Babel, preserve ES modules:

// babel.config.js
module.exports = {
  presets: [
    ['@babel/preset-env', { modules: false }]
  ]
}

Code Minification

Production mode automatically enables TerserPlugin for minification:

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          compress: {
            drop_console: true // Remove console
          }
        }
      })
    ]
  }
}

CSS minification uses css-minimizer-webpack-plugin:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new CssMinimizerPlugin()
    ]
  }
}

Image Optimization

Use image-webpack-loader for automatic image compression:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[hash].[ext]'
            }
          },
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false
              }
            }
          }
        ]
      }
    ]
  }
}

On-Demand Loading for Third-Party Libraries

Many libraries support on-demand loading, such as lodash:

// Full import (not recommended)
import _ from 'lodash';

// On-demand import
import debounce from 'lodash/debounce';

Or use a Babel plugin for automatic transformation:

npm install --save-dev babel-plugin-lodash

Babel configuration:

{
  "plugins": ["lodash"]
}

Ant Design also supports on-demand loading:

// babel-plugin-import
{
  "plugins": [
    ["import", {
      "libraryName": "antd",
      "libraryDirectory": "es",
      "style": "css"
    }]
  ]
}

Extract Common Dependencies

Separately bundle third-party libraries to avoid duplication:

module.exports = {
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
          name: 'vendor',
          chunks: 'all'
        }
      }
    }
  }
}

Use Lighter Alternatives

Evaluate dependency sizes and choose lighter alternatives:

  • moment → date-fns
  • lodash → lodash-es + on-demand imports
  • jQuery → native DOM operations (modern browsers)

Enable Gzip Compression

Webpack generates .gz files:

const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm: 'gzip',
      test: /\.(js|css)$/,
      threshold: 10240,
      minRatio: 0.8
    })
  ]
}

Optimize Source Maps

Use more compact source maps for production:

module.exports = {
  devtool: 'source-map' // Development
  // Production
  devtool: 'nosources-source-map'
}

Remove Development Code

Ensure production builds exclude development-specific code:

new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify('production')
})

Cache Optimization

Utilize long-term caching to reduce repeated downloads:

module.exports = {
  output: {
    filename: '[name].[contenthash].js'
  }
}

Multi-Threaded Building

Speed up the build process:

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

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          // ...
        }
      })
    ]
  }
}

Module Concatenation Strategy

Configure module merging rules appropriately:

module.exports = {
  optimization: {
    concatenateModules: true,
    runtimeChunk: 'single',
    moduleIds: 'deterministic'
  }
}

Check for Duplicate Dependencies

Use dependency-cruiser to analyze dependency relationships:

npx dependency-cruiser -T --exclude node_modules src

Use ESBuild for Faster Processing

Replace certain steps with ESBuild:

const { ESBuildMinifyPlugin } = require('esbuild-loader');

module.exports = {
  optimization: {
    minimizer: [
      new ESBuildMinifyPlugin({
        target: 'es2015'
      })
    ]
  }
}

Optimize Polyfills

Import polyfills on demand:

// babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'usage',
        corejs: 3
      }
    ]
  ]
}

Server-Side Rendering Optimization

Bundle size control for SSR scenarios:

// webpack.server.config.js
module.exports = {
  target: 'node',
  externals: [nodeExternals()],
  output: {
    libraryTarget: 'commonjs2'
  }
}

Monitor Bundle Size

Continuously track size changes:

const { BundleStatsWebpackPlugin } = require('bundle-stats-webpack-plugin');

module.exports = {
  plugins: [
    new BundleStatsWebpackPlugin()
  ]
}

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

如果侵犯了你的权益请来信告知我们删除。邮箱: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 ☕.