随着功能不断增加,不断迭代更新,React应用会越来越臃肿了,性能也将随之下降。本文从打包和运行两个方面着手,谈谈React应用改如何优化。
一、webpack打包优化
1、缓存node_moduels
我公司的项目每次上线部署的时候,虽然说都要要Jenkins上,但项目越来越多,每个项目部署占用时间都很长,导致每次部署完一个环境的所有项目耗费很多时间。
如果将同一项目的node_mudules
在每次打包完毕后缓存起来,下次打包前先判断是否与上次node_moduels
相同。若相同,则直接使用上次缓存的node_modules
,否则才重新安装依赖包。
那该如何实现上面所说的逻辑?
- 检查
packages.json
的md5
; - 打包完成后以该次
packages.json
的md5
值作为文件名,压缩node_modules
并缓存到指定位置; - 下次打包前,同样先检查当次
packages.json
的md5
,若相同直接使用上次的node_moduels
;
具体的SHELL如下:
1 |
|
2、加速代码压缩
webpack
提供的UglifyJS插件由于采用单线程压缩,速度很慢 ,webpack-parallel-uglify-plugin
插件可以并行运行UglifyJS
插件,这可以有效减少构建时间,当然,该插件应用于生产环境而非开发环境,配置如下:
1 |
|
3、HappyPack
加速构建
happypack
的原理是让loader可以多进程去处理文件,原理如图示:
目前项目中基本只对js和less文件使用HappyPack
加速,具体配置如下:
1 |
|
4、DLL
& DllReference
针对第三方NPM
包,这些包我们并不会修改它,但仍然每次都要在build的过程消耗构建性能,我们可以通过DllPlugin
来前置这些包的构建.
我们使用dllplugin
把第三方的NPM包生成一个名为 manifest.json
的文件,这个文件是用来让 DLLReferencePlugin
映射到相关的依赖上去的。在文件中引入该dll文件即可。
其原理是通过引用 dll
的 manifest
文件来把依赖的名称映射到模块的 id 上,之后再在需要的时候通过内置的 __webpack_require__
函数来 require
他们。
但对于antd
这样的按需加载UI库,不能放在dll
中,否则会全部打包进去,按需加载就无效了。
具体配置如下:
1 | ///dll.entry.js 定义dll的入口 |
然后在build.config.js
中加入dll插件:
1 | dllUtils.copyDllToAssets(), |
5、缓存dll
对于上文所说的,使用dll抽离第三方npm库可以加速打包,但还存在一种情况就是,dll可能很久不会改变,那每次build
的时候都要重新生成dll包,要不然每次收到复制到指定目录。
参考node_modules
的缓存机制,我们可以将生成的dll
包缓存起来,每次检查对象dll.entry.js
的md5
值,只要dll的入口定义不变则认为无需生成新的dll包。具体配置就不写了,跟上面的差不多。
6、其他
- 开启
devtool: "#inline-source-map"
会增加编译时间 DedupePlugin
插件可以在打包的时候删除重复或者相似的文件,实际测试中应该是文件级别的重复的文件- 减少构建搜索或编译路径
- 缓存与增量构建:
babel-loader
可以缓存处理过的模块,对于没有修改过的文件不会再重新编译,cacheDirectory
有着2倍以上的速度提升,这对于rebuild 有着非常大的性能提升。