webpack5 打包优化,让你的项目构建快到飞起

问题背景

目前项目开发较久文件较多,线上打包时间在有插件更新情况下超过 23min,平均时间在 20min,测试反应线上构建时间过长,急需优化(主要是缩短打包时间)

优化前的思考

本次优化的目标主要是针对构建时间,提升打包速度,打包速度的提升方向主要是在并行构建和合理利用缓存等方面进行入手 本次使用的 webpack 版本为 5.64.4。

优化准备

安装打包速度分析插件 speed-measure-webpack-plugin,使用插件分析打包时间

js 复制代码
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); // 打包速度分析

分析发现 在本地打包情况下 用时 8-10min 左右

优化方案

首次优化

并行构建

webpack 开启并行构建可以同时处理多个任务,提升构建效率 代码并行构建常用的是 HappyPack 和 Thread-loader,由于 HappyPack 官方已经不再维护了,上一次维护还是 5 年前,所以这次在多进程这方面采用的是与其类似的 Thread-loader。

Thread-loader 相较于 HappyPack 上手更为容易,只要把这个 loader 放在需要处理的其他 loader 之前使用就可以了。它是会创建多个 worker 来进行控制的,相当于把在它之后的 loader 处理放进一个独立的 worker 里面去执行。

添加多进程 Thread-loader

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        use: [
          // 开启多进程打包。
          {
            loader: "thread-loader", // 需要提前安装thread-loader插件
            options: {
              workers: 3, // 进程3个
            },
          },
          {
            loader: "babel-loader",
          },
        ],
      },
    ],
  },
};

需要注意的是,每个 worker 的开启都是需要一定的时间的,并不是开启的越多越好,只有在工程量大,代码量多的时候是会有明显提升的,所以使用前需要多加斟酌。

开启 cache 缓存,缓存 babel 编译,js 解析等。

webpack5 的 cache 属性,可以设置为 filesystem 进行缓存自定义的配置

没有缓存配置的 loader,可以使用 cache-loader 进行缓存,同样也是把它放在需要处理的 loader 之前使用即可。

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|mjs|jsx|ts|tsx)$/,
        use: ["cache-loader", "babel-loader"],
      },
    ],
  },
};

优化效果

  • 本地打包用时 6min,线上打包用时 15min

  • 对比原线上打包时间 20min,提升 25%

二次优化

对于优化后的效果感觉不够明显,又进行了二次优化

多次数度分析发现其中 source-map 和 terser-webpack-plugin 用时最久

针对这一情况进行优化,选择在开发环境及测试环境关闭 source-map(极大的减小体积及部分减少用时),关闭 terser-webpack-plugin(代码压缩混淆,极大的减少用时,会增加小部分体积)

我是在 package.json 中对不同环境利用 cross-env 传递变量,控制对不同环境的 source-map 和 terser-webpack-plugin 是否使用。

js 复制代码
 "build-dev": "cross-env DISABLE_TerserPlugin=true GENERATE_SOURCEMAP=false......"

在 webpack 配置中使用变量进行控制,对于需要使用 TerserPlugin 的情况,设置 parallel 为 true 可以开启并行压缩,提高效率。

js 复制代码
 optimization: {
   minimize: !disableTerserPlugin ? true : false,
   minimizer: [
     new TerserPlugin({
       parallel: true, // 启用并行压缩
       exclude: /node_modules/,
       terserOptions: {
         ......
       }
     }),
   ],}

优化效果

  • 本地打包时间用时 2min,线上打包用时在有插件下载情况下 4min30s 左右,平均用时 2min10s 左右, 体积从 440M 降低到 345M
  • 时间整体对比初始提升 90%,体积缩小 21.6%

对比效果图

首次优化对比

最终优化对比

对于采用控制 TerserPlugin 的思考

由于我们目前的项目是经常构建 dev 和 fat 环境,线上环境构建次数相对较少,不那么频繁,发版基本是按月发版的,所以真正影响构建工作效率的是 dev 和 fat 两个环境,所以采用了禁用 TerserPlugin 的方法去减少它的构建用时,但是真正到线上环境还是需要开启 TerserPlugin 进行代码压缩的。所以对于是否可以采用这种类似方法去适配其他项目,小伙伴们需要因地制宜,仔细考虑是否合适。

后序

  • 对于本次的优化结果,测试小伙伴表示非常满意,极大的提高了构建速度,减少了他们构建时需要等待的时间!
  • 本次优化方案的遗憾之处是没有找到更好的办法去各个环境都能达到一个满意的构建速度,比如线上环境,如果小伙伴们有更好的办法,欢迎提出!
  • 本文是作者对于个人的学习与总结笔记,如果有谬误的地方,欢迎各位提出并指正~
相关推荐
ew45218几秒前
【VUE】el-table表格内输入框或者其他控件规则校验实现
前端·javascript·vue.js
Lsx-codeShare1 分钟前
Uniapp 安装安卓、IOS模拟器并调试
android·前端·javascript·ios·微信小程序·小程序·uni-app
longlongago~~5 分钟前
DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放
前端·windows·node.js·音视频
爱上语文10 分钟前
Ajax入门程序
前端·javascript·css·ajax·html
北国13714 分钟前
python端拉流检测后再推流到流媒体服务器实现前端拉流查看(多摄像头切换)
服务器·前端·python·opencv·流媒体服务器
木子七17 分钟前
vue3-组件通信
前端·vue
乐闻x19 分钟前
Vue 是如何实现数据双向绑定的?
前端·vue.js
乐闻x21 分钟前
Vue 3 实现高性能拖拽指令的最佳实践
前端·javascript·vue.js
陈逸轩*^_^*33 分钟前
硅谷甄选前端项目环境配置笔记
前端·笔记
橙子家33 分钟前
Element-UI 中关于 Table 的几个功能点简介(行列的合并和样式、合计行配置等)
前端