【性能优化】Webpack打包优化

查看依赖

分析依赖树,找出哪些模块占用了较多的资源。

webpack-bundle-analyzer

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

webpack.config.js中添加插件配置:

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

module.exports = {
  // 其他配置项
  plugins: [
    // 其他插件
    new BundleAnalyzerPlugin({
      analyzerMode: 'static', // 生成静态报告文件
      openAnalyzer: false, // 构建完成后不会自动打开报告
      reportFilename: 'bundle-report.html' // 报告文件的名称
    })
  ]
};

打包完成后,dist文件中多出bundle-report.html文件,打开可以看到依赖占比。

一. 使用缓存

通过使用缓存,能够有效提升打包速度。

  • webpack5以下:cache-loader
  • webpack5:内置cache模块

内置cache模块

webpack5 内置了 cache 模块,缓存生成的 webpack 模块和 chunk,来改善构建速度。
在开发环境下,默认设置为 type: 'memory' 而在生产环境中被禁用。cache: { type: 'memory' }cache: true 作用一样,可以通过设置 cache: { type: 'filesystem' } 来开放更多配置项。

module.exports = {
  cache: {
    type: 'filesystem',
  },
};

会在 node_modules 目录下生成一个 .cache 目录缓存文件内容,二次打包速度显著提升。

cache-loader

安装

npm install cache-loader -D

在 webpack.config.js 对应的开销大的 loader 前加上 cache-loader。
注意:如果使用多线程加载器如 thread-loader 时,也需要确保 cache-loader 放在 thread-loader 之前。

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

二、多进程构建

同时开启多个 nodejs 进程进行构建

thread-loader

yarn add thread-loader -D
module.exports = {
  module: {
    rules: [
      {
        test: /.js$/,
        include: path.resolve('src'),
        use: [
          "thread-loader",
          // 耗时的 loader (例如 babel-loader)
        ],
      },
    ],
  },
};

注意:使用时,需将此 loader 放置在其他 loader 之前,放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
每个 worker 都是一个独立的 node.js 进程,开销大约为 600ms 左右。同时会限制跨进程的数据交换。所以请仅在耗时的操作中使用此 loader!(一般只在大型项目中的 ts、js 文件使用)

三、预编译资源模块

代替 cdn 分包,解决每个模块都得引用一个 script 的缺陷。

以 react 和 react-dom 为例,新建一个 webpack.dll.js 文件,用于预编译资源的打包,例如要对 react 和 react-dom 进行预编译,配置如下:

const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'production',
  entry: {
    library: ['react', 'react-dom'],
  },
  output: {
    filename: 'react-library.dll.js',
    path: path.resolve(__dirname, './dll'),
    library: '[name]_[hash]', // 对应的包映射名
  },
  plugins: [
    new webpack.DllPlugin({
      context: __dirname,
      name: '[name]_[hash]', // 引用的包映射名
      path: path.join(__dirname, './dll/react-library.json'),
    }),
  ],
};

package.json中新增命令

{
  // ...
  "scripts": {
    // ...
    "build:dll": "webpack --config ./webpack.dll.js"
  },
  // ...
}

执行 npm run build:dll后,webpack.config.js中:

const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require('./dll/react-library.json'),
    }),
    // 打包后的 .dll.js 文件需要引入到 html中,可以通过 add-asset-html-webpack-plugin 插件自动引入
    new AddAssetHtmlPlugin({ 
      filepath: require.resolve('./dll/react-library.dll.js'),
      publicPath: '',
    }),
  ],
};

四、移除未使用的代码

在 package.json 中添加 sideEffects 字段。
这个字段用于告知 Webpack,哪些文件或模块是无副作用的,哪些可能有副作用。

{
  "name": "your-project",
  "version": "1.0.0",
  "sideEffects": false
}

false 表示项目中所有模块都没有副作用,因此未使用的代码可以被安全地移除。

如果某些模块有副作用,可以用数组的形式列出这些模块:

{
  "sideEffects": ["./src/someSideEffectFile.js"]
}

你可能感兴趣的:(性能优化,性能优化,webpack,前端)