先简单总结一下,优化Webpack打包可以通过多种方式来提高性能和减小文件大小。以下是一些常见的优化技巧:
-
代码分割(Code Splitting) :将代码拆分成多个小块,使得在加载页面时只加载必要的代码。Webpack提供了多种代码分割的方法,如使用
import()
函数、SplitChunksPlugin
插件等。 -
懒加载(Lazy Loading):将不需要立即加载的模块延迟加载,提高页面初次加载速度。通常与代码分割一起使用。
-
压缩代码 :使用Webpack的
UglifyJsPlugin
或TerserPlugin
等插件来压缩和混淆JavaScript代码,减小文件大小。 -
优化图片 :使用
url-loader
或file-loader
来处理图片,可以将小图片转换为Data URL,或者通过图片压缩工具来减小图片大小。 -
Tree Shaking :通过
Tree Shaking
只打包项目中用到的代码,去除未使用的代码,减小打包体积。确保在Webpack配置中开启了Tree Shaking。注意,webpack5版本的树摇功能比webpack4版本做了很大改进,请升级到webpack5版本哦。 -
模块别名 :通过配置Webpack的
resolve.alias
来设置模块别名,减少模块路径的解析时间。
js
resolve: {// 设置模块如何被解析
alias: {
vue: "vue/dist/vue.esm-bundler.js"
},
extensions: ['.js', '.vue']// 按顺序解析这些后缀名
},
-
提取公共代码 :使用
SplitChunksPlugin
或者optimization.splitChunks
来提取公共代码,减少重复加载的代码,优化加载速度。 -
缓存 :通过设置
output.filename
和output.chunkFilename
的hash值,使得文件名带有内容哈希,实现文件内容变化时,浏览器能够正确缓存文件。 -
使用
Webpack Bundle Analyzer
:分析打包后的文件,找出体积较大的模块或者文件,针对性进行优化。 -
减少
loader
和plugin
的使用 :尽量减少不必要的loader
和plugin
的使用,因为它们会增加打包时间和文件大小。 -
使用
DLLPlugin
:将第三方库单独打包成一个动态链接库(DLL),可以减少每次打包时对第三方库的重新打包,提高打包速度。 -
缩小Webpack搜索范围 :通过配置
resolve.modules、resolve.extensions、resolve.mainFields
等参数,缩小Webpack搜索模块的范围,提高打包速度。 -
线上模式
mode: 'production'
和开发环境模式mode : 'development'
要区分设置,并根据不同的环境模式设置不同的devtool
值。
一起来实践吧
1.优化图片
除了用雪碧图和手动压缩图片大小,webpack也可以进一步自动化优化图片, 使用url-loader
或file-loader
处理图片,并且结合image-webpack-loader
来进行图片压缩:
js
// webpack.config.js
module.exports = {
// 其他配置...
module: {
rules: [
{
test: /.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 小于 8KB 的图片将转换为 base64
name: '[name].[hash:8].[ext]',
outputPath: 'images',
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75
}
},
},
],
},
],
},
};
2.开启Tree Shaking
确保在Webpack配置中开启Tree Shaking来消除未使用的代码:
js
// webpack.config.js
module.exports = {
// 其他配置...
optimization: {
usedExports: true,
},
};
3. 提取公共代码,进一步分包
js
optimization: {
minimizer: [new ESBuildPlugin()],
splitChunks: {
cacheGroups: {
defaultVendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
}
},
这段配置使用了Webpack 5中的 optimization
选项,并结合了 ESBuildPlugin
进行代码压缩。同时,使用了 splitChunks
选项来进一步优化打包结果。
-
minimizer: [new ESBuildPlugin()]
:这里使用了ESBuildPlugin
来进行代码压缩,它能够利用 ESBuild 引擎提供的快速压缩功能,提高构建效率。 -
splitChunks
:这个选项用于配置代码分割。在这个配置中,有两个cacheGroups
,分别是defaultVendors
和common
。-
defaultVendors
:用于提取第三方库,它的test
属性指定了匹配node_modules
中的模块。priority
设置了优先级,值越大,优先级越高。chunks: 'initial'
表示只对入口模块进行代码分割。 -
common
:用于提取共享模块,minChunks: 2
表示模块被引用至少两次时才会被提取。reuseExistingChunk: true
表示如果一个模块已经被提取过了,就会复用已经存在的模块,而不是再次创建一个新的模块。
-
这个配置能够有效地将第三方库和共享模块分割成独立的文件,以便利用浏览器的并行加载能力,提高应用的加载速度和性能。
4. 严格区分打包环境
在Webpack中,Source Map(源映射)是一种文件,它将编译后的代码映射回原始源代码。这对于调试和定位问题非常有用,因为它允许你在浏览器开发者工具中直接查看原始代码,而不是查看编译后的代码。Webpack支持多种类型的Source Map,你可以根据需求选择合适的类型。以下是一些常见的Source Map配置选项:
-
eval: 将Source Map作为 DataURL嵌入到打包后的JavaScript文件中,不会生成额外的文件,但会增加打包时间。
-
source-map : 生成单独的Source Map文件,以
.map
为后缀,对调试信息不作修改。 -
cheap-source-map: 生成单独的Source Map文件,但不包含列信息,对调试信息进行简化,提高构建速度。
-
cheap-module-source-map : 类似于
cheap-source-map
,同时对loader的Source Map也进行了处理,以便更好地定位到源代码中的错误位置。 -
inline-source-map: 将Source Map数据以DataURL的形式嵌入到打包后的JavaScript文件中,不会生成额外的文件,但会增加打包体积。
-
hidden-source-map: 生成单独的Source Map文件,但不在打包后的JavaScript文件中引用它,只在构建过程中用于调试。
-
nosources-source-map: 生成单独的Source Map文件,但不包含源代码内容,用于发布生产环境版本。
你可以通过在Webpack配置文件中设置devtool
选项来配置Source Map类型。例如:
javascript
module.exports = {
// 其他配置...
devtool: 'source-map',
};
如果你需要在生产环境中生成Source Map,通常建议使用hidden-source-map
、nosources-source-map
等选项,以确保源代码的安全性,并减小打包体积。而在开发环境中,可以选择更详细的Source Map类型,以方便调试和定位问题。
5.充分利用webpack5的持久化缓存(Persistent Caching)
Webpack 5 提供了一些缓存优化的功能,可以显著提高构建性能。以下是一些Webpack 5 中的缓存优化方式:
5.1. 持久化缓存(Persistent Caching)
Webpack 5 引入了持久化缓存,可以将构建过程中生成的缓存结果保存到磁盘上,以便下次构建时直接使用缓存,而不需要重新构建所有模块。这可以通过在配置文件中添加 cache.type
和 cache.buildDependencies
选项来实现:
javascript
module.exports = {
// 其他配置...
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename],
},
},
};
5.2. 并行构建(Parallelism)
Webpack 5 支持并行构建,可以同时处理多个构建任务,提高构建速度。你可以通过在配置文件中添加 parallel
选项来启用并行构建:
javascript
module.exports = {
// 其他配置...
parallelism: 4, // 同时处理的任务数量
};
5.3. 缓存组件(Caching Modules)
Webpack 5 使用 moduleIds
来标识模块,并且默认情况下会对模块的导出进行 hash 编码。你可以使用 optimization.moduleIds
选项来自定义模块标识的生成方式:
javascript
module.exports = {
// 其他配置...
optimization: {
moduleIds: 'deterministic', // 可选值: 'deterministic', 'size', 'total-size', 'hashed'
},
};
5.4. 模块缓存(Module Cache)
Webpack 5 支持模块级别的缓存,可以将经常引用的模块缓存起来,提高构建速度。你可以通过在配置文件中添加 cache
选项来启用模块缓存:
javascript
module.exports = {
// 其他配置...
cache: {
type: 'filesystem', // 持久化缓存
cacheDirectory: path.resolve(__dirname, '.webpack_cache'), // 缓存目录
},
};
通过使用这些缓存优化功能,Webpack 5 可以显著提高构建性能,尤其是对于大型项目和复杂项目来说,优化效果更加明显。
先写到这里,如果你还有想补充的,欢迎留言,一起学习交流哦!