性能优化

性能优化包括构建速度优化和运行时性能优化。本章介绍如何提升 Webpack 构建速度,以及如何优化应用的运行时性能。


📋 学习目标

  • ✅ 掌握构建速度优化技巧
  • ✅ 理解缓存策略
  • ✅ 学会使用多进程构建
  • ✅ 了解 DllPlugin 使用
  • ✅ 掌握运行时性能优化

构建速度优化

1. 使用缓存

文件系统缓存(Webpack 5)

module.exports = {
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename]
    }
  }
}

Babel 缓存

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true
          }
        }
      }
    ]
  }
}

2. 减少解析范围

module.exports = {
  resolve: {
    modules: [
      path.resolve(__dirname, 'src'),
      'node_modules'
    ],
    extensions: ['.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  }
}

3. 使用多进程构建

TerserPlugin 多进程

const TerserPlugin = require('terser-webpack-plugin')
 
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,  // 启用多进程
        terserOptions: {
          compress: {
            drop_console: true
          }
        }
      })
    ]
  }
}

thread-loader

npm install --save-dev thread-loader
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'thread-loader',
          'babel-loader'
        ]
      }
    ]
  }
}

4. 使用 DllPlugin

webpack.dll.js

const path = require('path')
const webpack = require('webpack')
 
module.exports = {
  mode: 'production',
  entry: {
    vendor: ['react', 'react-dom', 'lodash']
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_library',
      path: path.resolve(__dirname, 'dll/[name].manifest.json')
    })
  ]
}

webpack.config.js

const webpack = require('webpack')
 
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./dll/vendor.manifest.json')
    })
  ]
}

5. 减少文件监听

module.exports = {
  watchOptions: {
    ignored: /node_modules/,
    aggregateTimeout: 300,
    poll: 1000
  }
}

运行时性能优化

1. 代码分割

参考 代码分割 章节。

2. 懒加载

// React
const Component = lazy(() => import('./Component'))
 
// Vue
const Component = () => import('./Component.vue')

3. 预加载和预获取

// 预加载(高优先级)
import(/* webpackPreload: true */ './module')
 
// 预获取(低优先级)
import(/* webpackPrefetch: true */ './module')

4. 使用 CDN

module.exports = {
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  }
}

5. 资源压缩

const CompressionPlugin = require('compression-webpack-plugin')
 
module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm: 'gzip'
    })
  ]
}

性能监控

Speed Measure Plugin

npm install --save-dev speed-measure-webpack-plugin
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
 
module.exports = smp.wrap({
  // webpack 配置
})

Bundle Analyzer

npm install --save-dev webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

完整优化配置示例

const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
 
module.exports = {
  mode: 'production',
  
  // 缓存
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename]
    }
  },
  
  // 减少解析范围
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    extensions: ['.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  
  // 优化
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          compress: {
            drop_console: true
          }
        }
      })
    ],
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          priority: 10
        }
      }
    },
    runtimeChunk: 'single'
  },
  
  // 监听优化
  watchOptions: {
    ignored: /node_modules/
  }
}

最佳实践

1. 开发环境优化

  • 使用 eval-source-map(快速)
  • 禁用代码压缩
  • 使用 HMR

2. 生产环境优化

  • 使用 source-maphidden-source-map
  • 启用代码压缩
  • 启用 Tree Shaking
  • 使用 contenthash

3. 构建速度优化

  • 启用缓存
  • 减少解析范围
  • 使用多进程
  • 使用 DllPlugin(大型项目)

4. 运行时优化

  • 代码分割
  • 懒加载
  • 使用 CDN
  • 资源压缩

总结

  • 构建速度:缓存、多进程、减少解析范围
  • 运行时性能:代码分割、懒加载、CDN
  • 监控工具:Speed Measure、Bundle Analyzer
  • 最佳实践:区分开发和生产环境

下一步


Webpack 性能优化 构建速度 运行时性能