qappleh / Interview

我是追梦赤子心,公众号「深圳湾码农」的作者,某上市集团公司高级前端开发,深耕前端领域多年,每天攻破一道题,带你从0到1系统构建web全栈完整的知识体系!
https://github.com/qappleh/Interview
1.15k stars 97 forks source link

第43题(2019-09-19):怎么提高webpack打包速度?谈谈你的思路和方案 #45

Open qappleh opened 5 years ago

qappleh commented 5 years ago

"打包慢",是一个综合的因素,和vue关系不大。

1: 确保下webpack,npm, node 及主要库版本要新,比如:4.x比3.x提升很多。

2: loader范围缩小到src项目文件!一些不必要的loader能关就关了吧 例如:rules中loader添加:include: path.resolve(__dirname, 'src')

3: eslint代码校验其实是一个很费时间的一个步奏。 可以把eslint的范围缩小到src,且只检查.js 和 .vue 生产环境不开启lint,使用pre-commit或者husky在提交前校验

4: webpack-happypack从单进程变成多进程,加速代码构建速度

5: 动态链接库(DllPlugin),楼上已说。有点类似配置的externals。 补充一下: 缺点:将不能按需加载,会将配置的第三方库全部打包进去。 推荐:可以将使用率较高的包采用dll方案。

6: HardSourceWebpackPlugin会将模块编译后进行缓存,第一次之后速度会明显提升。

7: 使用webpack-bundle-analyzer对项目进行模块分析生成report,查看report后看看哪些模块体积过大,然后针对性优化,比如我项目中引用了常用的UI库element-ui和v-charts等

8: 配置webpack的externals ,官方文档的解释:防止将某些import的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖。 所以,可以将体积大的库分离出来:

// ...
externals: {
    'element-ui': 'Element',
    'v-charts': 'VCharts'
}  

然后在main.js中移除相关库的import

9: 使用 alias 可以更快地找到对应文件。

10: 如果在 require 模块时不写后缀名,默认 webpack 会尝试.js,.json 等后缀名匹配,配置 extensions,可以让 webpack 少做一点后缀匹配。

11: thread-loader 可以将非常消耗资源的 loaders 转存到 worker pool 中。

12: 使用 cache-loader 启用持久化缓存。使用 package.json 中的 postinstall 清除缓存目录。

13: 删除不需要的一些代码,利用SplitChunksPlugin 进行分块

14: 不同的devtool配置也会影响性能,最好配置为‘eval’,或者‘cheap-module-eval-source-map’

15: 开启gzip压缩,这个需要服务端配合,以Nginx为例 1)在config/index.js 里面设置 productionGzip:true; 2)安装稳定版本的compression-webpack-plugin,注意别着急安装,因为安装最新版本的容易报错; 3)在/build/webpack.base.config.js文件,找到module.exports的module中的rules,将图片类,音视频类,字体类加上limit选项,这样打包时可缩小静态资源体积 4)在Nginx服务端的配置中设置gzip:on gzip_static:on 2.对于引用的第三方库,可以通过CDN的方式,在index.html中引入,然后在build/webpack.base.config.js中,添加配置排除掉这些第三方引用:

//index.html
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://cdn.bootcss.com/vue/2.6.6/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script>
</body>
//webpack.base.config.js
let webpackConfig={ 
...
externals:{
'vue':'vue',
'vue-router':'vue-router',
'axios':'axios',
'echarts':'echarts'
}
...
}  

16: 因webpack提供的UglifyJS插件采用单线程压缩,速度很慢。所以将此插件替换为webpack-parallel-uglify-plugin插件,此插件可以并行运行UglifyJS插件,可有效减少构建时间。

//首先下载插件 npm i -D webpack-parallel-uglify-plugin
//修改 webpack.prod.conf.js
//将引入的UglifyJS 和 作用代码注释掉 并替换成下方代码
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
new ParallelUglifyPlugin({
          cacheDir: '.cache/',
          uglifyJS:{
              output: {
                  comments: false
              },
              compress: {
                  warnings: false,
                  drop_debugger: true,
                  drop_console: false
              }
          }
      }),  

详情可以参考webpack官方文档