本文深入解析Webpack构建打包的性能优化策略,涵盖提升开发体验的构建速度优化与改善生产环境的代码产出优化。通过配置Babel缓存、使用IgnorePlugin和noParse减少解析开销,结合HappyPack多进程打包与DllPlugin动态链接库技术显著缩短构建时间。同时,针对生产环境,介绍Base64编码、Hash缓存、公共代码提取及Tree-Shaking等技巧,旨在减小代码体积并提升加载速度。
前言
在开发阶段,若每次文件修改后Webpack能迅速完成编译构建,且浏览器能保持状态更新内容,将带来极佳的使用体验;而在生产环境中,通过优化产出代码、减小文件体积及设置Hash值,可有效提升网页的加载速度。
一、优化打包构建速度,提升开发体验和效率
1.1 优化babel-loader
开启缓存机制,确保未修改的ES6代码部分在下次重新构建时直接调用缓存,避免重复编译。
rules: [
{
test: /\.js$/,
loader: ['babel-loader?cacheDirectory'],
include: srcPath, //设置include或者exclude的范围,限定需要编译文件的目录范围
//exclude: /node_modules/
}
]1.2 IgnorePlugin,避免引入无用模块
例如部分库包含多国语言包(如moment.js),若仅需中文或英文包,应配置忽略不需要的语言包,避免引入冗余模块。
plugins: [
//忽略moment下的/locale目录,再手动import locale内部我们需要使用到的语言包
new webpack.IgnorePlugin(/\.\/local/,/moment/)
]1.3 noParse 避免重复模块化解析
对于已采用模块化处理的文件(如xx.min.js),无需再进行递归解析处理,配置noParse可防止此类文件被重复引入项目。
module: {
noParse: [/xx\.min\.js$/]
}1.4 happyPack 多进程打包
启用多进程打包机制,通过并行处理提高整体构建速度。
rules: [
{
test: /\.js$/,
//把对.js文件的处理转交给id为babel的HappyPack实例
use: ['happypack/loader?id=babel'],
include: srcPath
}
],
plugins: [
new HappyPack({
//用唯一的标识符id来代表当前的HappyPack是用来处理一类特定的文件
id: 'babel',
//如何处理.js文件,用法和loader配置中一样
loaders: ['babel-loader?cacheDirectory']
})
]1.5 ParallelUglifyPlugin多进程压缩js
该插件适用于生产环境,因开发阶段无需压缩JS代码,此步骤可节省构建时间。
plugins: [
new ParallelUglifyPlugin({
//还是使用的UglifyJs压缩,只不过帮助开启了多进程
uglifyJS: {
output: {
beautify: false,//最紧凑的输出
comments: false,//删除所有的注释
},
compress: {
//删除所有的'console'语句,可以兼容ie浏览器
drop_console: true,
//内嵌定义了但只用到一次的变量
collapse_vars: true,
//提取出出现多次但是没定义成变量去引用的静态值
reduce_vars: true
}
}
})
]1.6 热更新
代码修改后,浏览器无需刷新即可生效新代码,并保留当前状态。
entry: {
index: [
'webpack-dev-server/client?http://localhost:8080/',
'webpack/hot/dev-server',
path.join(srcPath, 'index.js')
],
other: path.join(srcPath, 'other.js')
}
plugins: [
new HotModuleReplacementPlugin()
]
devServer: {
xxx: 'xx'
hot: true //开启热更新
}配置完成后,样式修改可触发热更新,但JS修改若未生效,需在JS中设置允许热更新监听的模块。
if(module.hot){
module.hot.accept(['xxx文件名'], () => {
//在注册了热更新的js文件修改后,才会进行热更新
})
}1.7 DllPlugin动态链接库插件
针对Vue、React等大型且稳定的前端框架,构建缓慢且不常升级版本时,可固定版本仅构建一次。Webpack内置DllPlugin,包含DllPlugin(打包dll文件,后续无需重复打包)和DllReferencePlugin(使用dll文件)。
//webpack.dll.js文件中的配置
mode: 'development',
entry: {
//把react相关模块放到一个单独的动态链接库
react: ['react','react-dom']
},
output: {
//输出动态链接库的文件名称,[name]代表当前动态链接库的名称
filename: '[name].dll.js',
path: distPath,
//存放动态链接库的全局变量名称,例如对应react来说就是 _dll_react
//之所以在前面加上_dll_是为了防止全局变量冲突
library: '_dll_[name]'
}
plugins: [
new DllPlugin({
//动态链接库的全局变量名称,需要和output.library中保持一致
//该字段的值也就是输出的manifest.json文件中name字段的值
name: '_dll_[name]',
path: path.join(distPath, '[name].manifest.json')
})
]配置webpack.dll.js后,需在package.json中定义执行该配置文件的命令。
"script": {
"dll": "webpack --config build/webpack.dll.js"
}执行dll打包命令后,将生成react.dll.js和react.manifest.json文件,项目中需引用打包后的react.dll.js。
//在inde.html中
<script src="./react.dll.js"></script>
//在webpack.dev.js中
plugins: [
new DllReferencePlugin({
//描述react动态链接库的文件内容
manifest: require(path.join(distPath, 'react.manifest.json'))
})
]二、webpack性能优化-产出代码
可从减小体积、合理分包避免重复加载、提升速度及降低内存使用等方面对产出代码进行优化。
- 2.1 小图片base64编码,使用url-loader,可减少网络请求
- 2.2 bundle加hash,如果文件没有变,hash值不变,浏览器可以命中缓存
- 2.3 提取公共代码,可以是整个项目的体积更小
- 2.4 IngorePlugin 忽略库中不需要的包
- 2.5使用cdn加速
output: {
publicPath: 'http://cdn.xxx.com'//引用文件路径是,路径名前加cdn域名的前缀
}打包后,将代码部署至CDN域名对应的服务器中。
- 2.6 使用production
当mode设置为production时,打包代码会自动压缩;Vue/React会自动移除调试代码(如开发环境的warning);同时自动启用Tree-Shaking,删除未使用的代码。
mode: "production"- 2.7 Scope Hosting
将多个函数合并至一个函数中,可减小代码体积,减少创建的函数作用域数量,并提升代码可读性。
module.exports = {
resolve: {
mainFields: ['jsnext: main','browser','main']
},
plugins: [
//开启Scope Hosting
new ModuleConcatenationPlugin()
]
}总结
至此,关于Webpack构建打包性能优化的内容介绍完毕,更多相关Webpack构建打包性能优化内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!