本文中全部的测试都基于 2017款15寸MacBook Pro低配版本html
关于dll的介绍已经有不少文章了,webpack性能优化都无可避免的会提到dll。在webpack 4已经进入生涯晚期,webpack 5已经发了几十个alpha版本的时间节点,咱们是否还须要dll这个优化手段。vue
dll的做用是将项目中一些不常改变的依赖单独打包,webpack经过生成的manifest文件去引用对应的依赖。node
webpack 4相比于3增长了不少新的特性,而且根据mode增长了不少的默认配置。react
其中和dll关系比较大的改变是在webpack 4中用terser来对文件进行压缩混淆,替换了原来的uglifyjs,而且默认开启了多进程和缓存。webpack
@vue/cli在3.0的版本中再也不支持dll,可能也和webpack 4在打包的时候默认开启缓存有关,由于dll说到底其实也是一种文件的缓存机制。web
那咱们是否再也不须要dll呢?json
通常的项目开发过程当中,都避不开两个场景。一个是本地开发,须要运行webpack-dev-server启动一个本地服务;一个是线上发布,须要运行build命令,对项目进行打包而后进行代码发布。缓存
对于项目打包,特别是升级到webpack 4之后,dll就显得有点不合时宜。一方面是由于terser的缓存机制已经很优秀了,另外一方面是由于webpack 4中的sideEffects机制。性能优化
在webpack 4 中增长了sideEffects机制,一个包若是在package.json中声明了sideEffects为false,那么webpack会认为这个包中的各个模块是无反作用的,对于没有用到的模块就不会去加载,作到了文件级别的按需加载。对于那些已经使用了sideEffects来实现按需加载的包,咱们在最终项目打包的时候能够作到按需打包,不会对这个包作全量引入。相似的还有lodash和antd这些经过babel插件来实现按需引入的包,最终打包的时候也不会全量引入整个包。babel
可是若是使用dll来处理这些第三方依赖的包,就会把这个包全量引入进来,最终的代码里会有不少多余的代码,最终代码的大小也会增长不少。
webpack对于依赖的收集,会从配置的入口文件开始,去作递归的解析,最后生成一个依赖图。
在每次运行dev-server的时候,webpack都会从新去收集全部的依赖。terser只会在打包压缩的时候才会运行,因此在dev的时候是没有办法进行缓存的。babel-loader也能够进行缓存设置,可是通常的项目为了加快构建速度,都会默认不去处理node_modules里面的依赖,因此第三方的依赖包没法被编译缓存。
在这种状况下,dll的引入就会带来巨大的性能提高。使用dll对第三方依赖进行缓存,只要依赖版本不变动,那么webpac依赖解析就能够跳过全部node_modules里面的依赖文件,大大减小dev-server的启动时间。
对于时间的测试,若是只是使用脚手架create一个没有什么依赖的空项目,那不会有任何意义。
为了还原真实场景的数据,这里将用一个PC的项目进行测试。主要的依赖有react全家桶、@babel/polyfill、antd和loadsh。可是项目的业务代码并非不少,因此在某些时间上面可能会有必定的误差。
绝大多数使用了缓存进行优化的项目,在项目第一次运行的时候都不会有效果,由于这时候的缓存文件尚未生成。
在仅使用babel-loader缓存的状况下,dev-server的启动时间以下
类型 | 启动时间 |
---|---|
首次启动 | 22s |
第二次 | 17.7s |
第三次 | 18.1s |
第四次 | 17.8s |
能够看出在首次启动的时候,由于babel-loader尚未缓存,因此这时候启动时间最长。当缓存生成之后,启动时间就会有一个减小。
当启用dll之后,启动时间以下
类型 | 启动时间 |
---|---|
首次启动 | 27.6s |
第二次 | 5.1s |
第三次 | 4.8s |
第四次 | 4.9s |
在首次启动的时候,花费的时间比没有dll的要多一些,其中生成dll文件的时间为19s。可是当dll文件生成之后,再次启动的时间会有巨大幅度的减小,由于webpack对于dll中的依赖不用再作任何的解析和处理。
hard-source-webpack-plugin也提供了缓存系统,能够做为dll的代替方案。
相比于dll,它配置更简单,只须要增长一个plugin配置便可。可是在项目启动时间上,要比dll的方案慢一秒左右。
类型 | 启动时间 |
---|---|
首次启动 | 21.8s |
第二次 | 6.1s |
第三次 | 6.3s |
第四次 | 6.0s |
可是在项目打包的时候,hard-source-webpack-plugin带来的提高是巨大的。缓存生成之后,build的时间从15s减小到5s。
不过hard-source-webpack-plugin中止维护快一年的时间了,这可能也是一个须要考虑的问题;另外一个须要考虑的问题是它的缓存文件很是大,会占用很是多的硬盘空间。
在同时开启dll和hard-source-webpack-plugin的时候,当缓存同时生效的状况下,项目启动只须要两秒左右的时间,相比于开启单个功能,时间分别减小了一半和三分之二。
类型 | 启动时间 |
---|---|
首次启动 | 27.3s |
第二次 | 2.1s |
第三次 | 2.1s |
第四次 | 2.2s |
webpack 5的alpha版本最近增长的很快,做者已经加快了开发速度。webpack 5中实验性的内置了一个文件缓存系统,能够彻底替代hard-source-webpack-plugin、babel-loader以及一系列的缓存方案。
可是如今还有不少webpack的第三方插件没有对webpack 5作兼容,好比html-webpack-plugin。但愿webpack 5正式发布的时候可以获得解决。
在webpack 5到来以前,使用hard-source-webpack-plugin,配合babel-loader,能得到至关可观的缓存优化。
本地开发阶段若是加入dll,可使得项目启动时间进一步减小,缩短等待项目启动的发呆时间。