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 进行代码压缩的。所以对于是否可以采用这种类似方法去适配其他项目,小伙伴们需要因地制宜,仔细考虑是否合适。

后序

  • 对于本次的优化结果,测试小伙伴表示非常满意,极大的提高了构建速度,减少了他们构建时需要等待的时间!
  • 本次优化方案的遗憾之处是没有找到更好的办法去各个环境都能达到一个满意的构建速度,比如线上环境,如果小伙伴们有更好的办法,欢迎提出!
  • 本文是作者对于个人的学习与总结笔记,如果有谬误的地方,欢迎各位提出并指正~
相关推荐
CoolerWu12 小时前
TRAE SOLO实战成功展示&总结:一个所见即所得的笔记软体
前端·javascript
Cassie燁12 小时前
el-button源码解读1——为什么组件最外层套的是Vue内置组件Component
前端·vue.js
vx_bscxy32212 小时前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
北极糊的狐12 小时前
Vue3 子组件修改父组件传递的对象并同步的方法汇总
前端·javascript·vue.js
spionbo12 小时前
Vue3 前端分页功能实现的技术方案及应用实例解析
前端
AI绘画小3312 小时前
Web 安全核心真相:别太相信任何人!40 个漏洞挖掘实战清单,直接套用!
前端·数据库·测试工具·安全·web安全·网络安全·黑客
7***n7512 小时前
前端设计模式详解
前端·设计模式·状态模式
用户479492835691513 小时前
Vite 中 SVG 404 的幕后黑手:你真的懂静态资源处理吗?
前端·vite
未来之窗软件服务13 小时前
幽冥大陆(三十五)S18酒店门锁SDK go语言——东方仙盟筑基期
java·前端·golang·智能门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk
卸任13 小时前
解密Flex布局:为什么flex:1仍会导致内容溢出
前端·css·flexbox