[每日一答]:简述如何优化webpak构建速度

183 阅读3分钟

如何优化 webpack 构建速度

这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

导语

优化webpack构建速度,我们需要实现优化前后的对比,这里我们会将没有优化的构建速度,以及每做一次优化后的构建速度拿来做对比,来直观感受优化的可行性。

如何实现监控webpack构建时间

推荐使用插件: speed-measure-webpack-plugin

这款工具可以实现在webpack打包的同时,记录每一个loader打包的时间以及打包总共时长。

安装:

npm install --save-dev speed-measure-webpack-plugin

配置:

const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin({
  outputFormat: 'human'
})


configureWebpack: smp.wrap({
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    }
})

使用 smp.wrap包裹 webpackConfig即可

执行打包:(根据项目的打包命令来)

npm run build:prod 在打包完成后可以看到以下的输出:

image.png

这里可以清楚记录每个loader的打包时间,以及总共的打包时间。

在未做优化前,打包时间为 6.54s

include/exclude

webpack 中所有的loader 都可以拥有include和exclude属性。

exclude:排除不满足条件的文件夹(这样可以排除webpack查找不必要的文件)

include:需要被loader 处理的文件或文件夹

我们可以将 node_modules 第三方依赖的loader处理进行排除:

module: {
      rules: [
        {
          test: /\.jsx$/,
          exclude: [
            path.resolve(__dirname, 'node_modules')
          ],
          loader: 'babel-loader'
        }
      ]
    }

image.png

打包时间提升到了5.87s,这也是官方推荐的一种优化方案。

cache-loader

cache-loader 允许缓存以下 loaders 到(默认)磁盘或数据库。

安装:

npm install --save-dev cache-loader

配置:

module: {
      rules: [
        {
          test: /\.js$/,
          use: [
            'cache-loader',
            'babel-loader'
          ],
          include: path.resolve('src')
        }
      ]
    }

image.png

优化结果为 5.7s,效果不明显的原因可能是本身缓存读取就会消耗性能,如果本身loader的加载时间就很短,就没有必要使用 cacher-loader

官方提醒:

⚠️ 请注意,保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此 loader。

多线程 thread-loader

安装:

npm install thread-loader --save

配置:

configureWebpack: smp.wrap({
    name: defaultSettings.title,
    devtool: 'source-map',
    resolve: {
      alias: {
        '@': resolve('src'),
        '@components': resolve('src/components'),
        '@views': resolve('src/views'),
        '@api': resolve('src/api'),
        '@utils': resolve('src/utils'),
        '@public': resolve('public')
      }
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          use: [
            'thread-loader', 'cache-loader', 'babel-loader'
          ],
          include: path.resolve('src')
        }
      ]
    }
  })

结果: image.png

似乎并没有什么用,但可能是因为我的项目太小,如果在实际大项目或者loader比较多的情况下可能会有明显作用,这里大家可以自行选择和尝试。

缓存 HardSourceWebpackPlugin

安装:

npm install hard-source-webpack-plugin -D

配置:

configureWebpack: smp.wrap({
    name: defaultSettings.title,
    devtool: 'source-map',
    resolve: {
      alias: {
        '@': resolve('src'),
        '@components': resolve('src/components'),
        '@views': resolve('src/views'),
        '@api': resolve('src/api'),
        '@utils': resolve('src/utils'),
        '@public': resolve('public')
      }
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          use: [
            'thread-loader', 'cache-loader', 'babel-loader'
          ],
          include: path.resolve('src')
        }
      ]
    },
    plugins: [
      new HardSourceWebpackPlugin()
    ]
  })

效果:

image.png

这里的效果还是相当明显的,直接节省了将近一半的时间,首次构建不会节约时间,首次构建会创建缓存,在之后的构建会起到一定的作用。

noParse

webpack精准过滤不需要解析的文件

配置:

configureWebpack: smp.wrap({
    name: defaultSettings.title,
    devtool: 'source-map',
    resolve: {
      alias: {
        '@': resolve('src'),
        '@components': resolve('src/components'),
        '@views': resolve('src/views'),
        '@api': resolve('src/api'),
        '@utils': resolve('src/utils'),
        '@public': resolve('public')
      }
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          use: [
            'thread-loader', 'cache-loader', 'babel-loader'
          ],
          include: path.resolve('src')
        }
      ],
      noParse: /jquery|lodash/
    },
    plugins: [
      new HardSourceWebpackPlugin()
    ]
  })

结果:

image.png

可以发现,成功把打包时间压缩到了3s以下。

总结

其实优化webpack的打包速度的方法还有很多,这里只是常用的一些方案。今天案例,成功将原先的6.54s的打包时间,压缩到了2.99s。其中用到:

等等等等