umi项目构建加速:多进程 / externals / cache

好长时间了,我的umi项目打包速度好慢。不管是平时启动开发模式,还是生产模式打包。测了一下,生产模式每次打包大概要2分钟左右。下决心优化一下。

另外,umi其实在打包加速方面已经开箱即用地帮我们做了很多优化,所以我们即使什么都不做,目前看到的打包速度,已经是umi上了种种优化手段之后的结果了。

这里主要记录一下我尝试的一些主流的、umi默认没有使用的加速手段。

❌多进程打包 ------ happypack / thread-loader

webpack对文件的解析和处理默认是单线程的,文件数量很多时,解析和处理文件的时间就会越来越长,打包的速度就会变慢。

happypackthread-loader都是通过多进程打包来提升webpack打包速度。happypack目前已经不再维护了,所以更推荐使用thread-loader

在umi中更改处理文件的loader需要使用webpack-chain的api。配置thread-loader需要把它添加到module.rule.use数组的第一个。

在此贴一下umi配置thread-loader的代码:

javascript 复制代码
//config/config.ts 
chainWebpack(config, { webpack }) {
  config.module
    .rule("js")
    .use("thread-loader")
    .loader("thread-loader")
    .before("babel-loader");
    
  config.module
    .rule("ts-in-node_modules")
    .use("thread-loader")
    .loader("thread-loader")
    .before("babel-loader");
    
  config.module
    .rule("js-in-node_modules")
    .use("thread-loader")
    .loader("thread-loader")
    .before("babel-loader");
}

配置完成后可以通过config.toString()查看修改后的完整配置。

但是在配置thread-loader之后,发现对打包速度并没有提升,基本上没变化。查了一下,发现它对加速的loader是有要求的,不允许使用自定义loader的api。

umi中使用的loader是umi封装过的,而不是原装的babel-loader等。这是umi中的部分loader配置:

所以thread-loader配置之后也没有起到加速效果,多进程打包在umi这里没有走通。

❌externals

我们项目中总是有一些很少更新的、体积又不小的第三方库,比如react / react-dom / lodash等。这些库很少发生更改,但是我们每次打包都要把它们重新构建一遍。这就造成了打包时间的浪费。为了节省这部分时间,我们就要用到webpack的externals

externals配置用于将一些第三方库排除出打包过程,不出现在最终的打包结果中。再通过其他方式引入它们,比如<script>标签引入。

举个栗子:我们可以像这样配置externals,它的值是一个对象,key是第三方库的名字,value是通过<script>引入的全局变量的名字:

javascript 复制代码
{
  //...other webpack config
  externals: { 
    react: "React", 
    lodash: "_", 
    "react-dom": "ReactDOM" 
  },
};

这样,我们就可以把react / react-dom / lodash排除出打包过程,减少webpack需要打包的模块数量,以提升webpack的打包速度。

之后,不要忘记在项目的html中手动引入这些依赖包:

html 复制代码
<script src="https://unpkg.com/react@16.14.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.14.0/umd/react-dom.production.min.js"></script> 
<script src="https://raw.githubusercontent.com/lodash/lodash/4.17.21-npm/lodash.min.js"></script>

至此,externals的配置就OK了。但是实际上,我测了一下,对项目的打包速度提升很有限。可能是我的项目原本的体积比较大。

另外,还有一个问题,就是externals虽然将这些第三方库排除出了打包过程,参与打包过程的模块是少了。但并不意味着我们需要加载的文件体积减少了。通过<script>引入的文件,依然需要加载。而且通过<script>引入的这些文件,不参与打包,webpack是没有办法对其进行tree shaking的。所以对于支持tree shaking的库要注意,通过<script>引入的文件体积是不是比原来打包的产物体积大很多。

比如antd,支持tree shaking,官方文档里也提到,虽然支持通过<script>标签引入,但不建议这么做。

✔ cache

webpack 5提供了新的特性:cache。开启cache之后,webpack会将首次打包的结果持久化到本地文件系统中。在下一次构建时,对于未更新的文件,跳过解析、链接、编译等一系列非常消耗性能的操作,直接复用上一次打包的结果。通过这种方式,大幅度提升打包速度。

在umi项目中,需要手动开启cache。我的项目是umi v3。通过如下选项开启:

javascript 复制代码
{ 
  //...other umi config 
  webpack5: {} 
}

开启之后,打包快了很多很多。开启之前,每次build大概105s左右;开启之后,大概12s左右。

umi v3默认使用webpack 4打包。如果不想开启webpack 5,不用webpack 5的cache特性的话,可以考虑通过cache-loader / DLL plugin等在webpack 4中实现缓存。

相关推荐
鹧鸪yy1 分钟前
认识Node.js及其与 Nginx 前端项目区别
前端·nginx·node.js
跟橙姐学代码2 分钟前
学Python必须迈过的一道坎:类和对象到底是什么鬼?
前端·python
汪子熙4 分钟前
浏览器里出现 .angular/cache/19.2.6/abap_test/vite/deps 路径究竟说明了什么
前端·javascript·面试
Benzenene!5 分钟前
让Chrome信任自签名证书
前端·chrome
yangholmes88885 分钟前
如何在 web 应用中使用 GDAL (二)
前端·webassembly
jacy7 分钟前
图片大图预览就该这样做
前端
林太白9 分钟前
Nuxt3 功能篇
前端·javascript·后端
YuJie11 分钟前
webSocket Manager
前端·javascript
Mapmost26 分钟前
Mapmost SDK for UE5 内核升级,三维场景渲染效果飙升!
前端
Mapmost29 分钟前
重磅升级丨Mapmost全面兼容3DTiles 1.1,3DGS量测精度跃升至亚米级!
前端·vue.js·three.js