写点什么

Webpack | 如何提升构建速度,进行体积优化?

用户头像
梁龙先森
关注
发布于: 2021 年 02 月 04 日
Webpack | 如何提升构建速度,进行体积优化?

上篇文章,已经说明了进行优化的前期准备,如何查看构建统计信息、速度分析,以及体积分析。这篇文章就写写,如何进行具体的优化。

1. 构建速度优化

1. 使用高版本工具的福利

高版本的 webpack 和 node.js 能带来构建时间上的提升,以 webpack4 为例。

  1. V8 上的优化,提升了代码执行效率。比如:

for of 替换 forEach | Map 和 Set 替换 Object | Includes 替换 indexOf

  1. 默认使用更快的 md4 hash 算法

  2. webpack AST 可以直接从 loader 传递给 AST,减少间隙时间

  3. 使用字符串方法替换正则表达式

2. 资源并行解析

这里使用 thread-loader 并行解析资源,大概原理是:每次 webpack 解析一个模块,loader 会将它的依赖分配给 worker 线程处理。用法如下:

module.exports = {	module:{  	rules:[      {      	test:/.js$/,        include: path.resolve('src'),        use:[          {        		loader:'thread-loader',          	options:{              // 开启线程数          		workers:3,               // 额外的nodejs参数              workerNodeArgs: ['--max-old-space-size=1024']             	// 其他更具体参数,查看文档          	},        	},          'babel-loader'        ]      }    ]  }}
复制代码

说明:thread-loader 要放在其他 loader 之前,随后的 loader 将在工作池中运行。每个工作程序都是一个单独的 node.js 进程,其开销约为 600 毫秒,并且进程间通信也有开销,因此这个 loader 只能用于一些昂贵的操作。

3. 并行压缩
  1. 使用 parallel-uglify-plugin 插件

const ParallelUglifyPlugin = require('parallel-uglify-plugin')// 更详细配置查看官网module.exports = {	plugins:[  	new ParallelUglifyPlugin({    	uglifyJS:{      	output:{        	beautify:false,          comments:false        },        compress:{        	warning:false,          drop_console:true        }      }    })  ]}
复制代码
  1. 使用 uglifyjs-webpack-plugin 插件

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')module.exports = {	plugins:[  	new UglifyJsPlugin({      parallel:true,  // 开启并行    	uglifyOptions:{        // 其他配置查看官网      }    })  ]}
复制代码
  1. 使用 terser-webpack-plugin 插件

const TerserPlugin = require('terser-webpack-plugin')module.exports = {	optimization:{  	minimizer:[    	new TerserPlugin({      	 parallel:3  // 开启并行数      })    ]  }}
复制代码

2. 构建体积优化

1. 分包:设置 Externals

通过 html-webpack-externals-plugins,将一些基础包通过 cdn 引入,不打入 bundle。

const HtmlWebpackExternalsPlugins = require('html-webpack-externals-plugins')module.exports = {	new HtmlWebpackExternalsPlugins({		externals:[  		{  			module:'vue',  			entry:'//***/vue.min.js',        global:'Vue'			}  	]	})}
复制代码

这种方式构建完成后,会在 index.html 创建多个 script 标签,分别引入对应的库(配置的 entry).

2. 分包:预编译资源模块

思路:将基础包(react/react-dom 等)和业务基础包打包成一个文件

方法:使用 DLLPlugin 插件进行分包,DllReferencePlugin 对 maniffest.json 引用

实现流程如下:

  1. 根目录编写配置文件:webpack.dll.config.js

const path = require("path");const webpack = require("webpack");const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const library = { vue: ["vue", "vue-router", "vuex"], // 值越多,抽取的文件越大,键为抽取的文件名 others: ["axios", "js-cookie"],}
// dll文件存放的目录const dllPath = "public/baselib";module.exports = { // 入口文件 entry: { ...library }, // 输出文件 output: { path: path.join(__dirname, dllPath), filename: "MyDll.[name].js", library: "[name]_[hash]" }, plugins: [ // 清除上一打包产生的dll文件 new CleanWebpackPlugin(), new webpack.DllPlugin({ path: path.join(__dirname, dllPath, "[name]-manifest.json"), name: "[name]_[hash]" }) ]};
复制代码
  1. package.json 添加打包命令

{	"scripts":{  	"dll":"webpack -p --progress --config ./webpack.dll.conf.js"  }	}
复制代码
  1. 执行命令,产生文件

执行命令:npm run dll,会产生如下文件

public/baselib/vue-manifest.json

public/baselib/others-manifest.json

public/baselib/MyDll.vue.js

public/baselib/others.js

  1. webpack 配置 DllReferencePlugin

const path = require("path");const webpack = require("webpack");const dllPath = "./public/baselib/";
// 应当处理出公共配置const library = { vue: ["vue", "vue-router", "vuex"], others: ["axios", "js-cookie"],}
plugins: [ ...Object.keys(library).map(name => { return new webpack.DllReferencePlugin({ context: ".", manifest: path.join(dllPath, `${name}-manifest.json`) }); })]
复制代码
  1. 模板文件引入 js

<body>  <!--文件路径中<%= BASE_URL %>为vue cli 3中读取根目录的写法,使用其他框架的请使用自己的写法-->	<script src="<%= BASE_URL %>baselib/MyDll.vue.js"></script>	<script src="<%= BASE_URL %>baselib/MyDll.others.js"></script></body>
复制代码

只要运行 np run dll 命令打包一次即可,若配置有更改,则需重新打包以及引入文件。

3. 总结

至此我们完成了 webpack 速度优化和体积优化策略的学习,当然还有设计其他优化策略,下一章继续。

发布于: 2021 年 02 月 04 日阅读数: 28
用户头像

梁龙先森

关注

脚踏V8引擎的无情写作机器 2018.03.17 加入

还未添加个人简介

评论

发布
暂无评论
Webpack | 如何提升构建速度,进行体积优化?