关于 webpack 的性能优化这块,前面已经写了两篇 2 章,一篇是介绍性能优化前的分析,另一篇是介绍速度提升和体积优化的主要方式,文章如下:
如何进行构建速度分析和体积分析?
如何提升构建速度,进行体积优化?
当然你如果对 webpack 原理,以及 loader 和 plugin 实现感兴趣也可以访问如下文章:
浅谈Webpack的本质
Loader处理非JavaScript模块详解
Plugin事件流机制详解
浅谈Webpack原理,以及loader和plugin实现
当然还有其他一些 webpack 的基础进阶用法文章,如下:
wepback进阶用法1:多入口构建/资源内联/脚本分离等
webpack进阶用法2:代码分割和动态引入的实现方式
webpack进阶用法3:如果将代码打包成一个通用JS库
接下去进入主题,了解 webpack 性能优化的其余几种方式:
1. 缓存:提升二次构建速度
babel-loader 开启缓存
babel-loader 的 cacheDirectory 属性默认值是 false。如果设置了这个参数,被转换的结果将会被缓存起来。当 webpack 再次编译时,将会首先尝试从缓存中读取转换结果,以此避免资源浪费。
module.exports = {
module:{
rules:[
{
test:/\.js$/,
use:['babel-loader?cacheDirectory=true'],
exclude:/node_modules/
}
]
}
}
复制代码
使用 cache-loader
cache-loader 仅限于在性能开销较大的 loader 之前添加它,以便将结果缓存到磁盘。这是因为保存和读取这些缓存文件存在时间开销。
module.exports = {
module:{
rules:[
{
test:/\.js$/
use:[
'cache-loader',
'babel-loader'
],
include:path.resolve('src')
}
]
}
}
复制代码
使用 hard-source-webpack-plugin
这是 4.0 与 5.0 之间的一种过渡的使用缓存的方式。
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
plugins:[
new HardSourceWebpackPlugin()
]
}
复制代码
terser-webpack-plugin 开启缓存
用于压缩 js 的插件,webpack5 已经集成最新版,当然如果还是用 4 版本的,可以留意下。
new TerserPlugin({
parallel:true,
cache:true // 开启缓存
})
复制代码
2. 减少文件搜索范围
优化 loader 配置
module.exports = {
module:{
rules:[
{
test:/\.js$/,
use:['babel-loader?cacheDirectory=true'],
// 只对src目录下的文件进行babel-loader转换
include: path.resolve(__dirname, 'src')
}
]
}
}
复制代码
优化 resolve.modules 配置
resolve.modules
的默认值是 ['node_modules']
,查找规则是从当前目录一级一级往上查找,直至找到想找的模块。但如果我们三方库都放在根目录的node_modules
底下,则可如下配置,减少查找。
module.exports = {
resolve:{
// 用于配置webpack从哪些目录下寻找第三方模块
modules:[
path.resolve(__dirname,'node_modules')
]
}
}
复制代码
优化 resolve.mainFields 配置
module.exports = {
resolve:{
// package.json描述第三方模块的属性
// 用于配置第三方模块使用哪个字段入口文件
mainFields:['main']
}
}
复制代码
优化 resolve.alias 配置
resolve.alias
配置项可以通过别名来把原导入路径映射成一个新的导入路径。
module.exports = {
resolve: {
// 通过 alias 把导入 vue 的语句换成直接使用单独完整的 vue.min.js 文件,
// 减少耗时的递归解析操作
alias: {
'vue': path.resolve(__dirname, './node_modules/vue/dist/vue.min.js'),
}
},
}
复制代码
优化 resolve.extensions 配置
resolve.extensions
用于配置在当导入语句没带文件后缀时,webpack 尝试询问文件是否存在使用的后缀列表。
module.exports = {
resolve: {
// 尽可能减少后缀尝试的可能性
extensions: ['js'],
},
}
复制代码
3. 图片压缩
采用 image-webpack-loader 进行图片压缩
rules: [{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
// 以下是针对每种图片类型优化器的配置
mozjpeg: { // 压缩jpeg
progressive: true,
},
// optipng.enabled: false will disable optipng
optipng: { // 压缩png
enabled: false,
},
pngquant: { // 压缩png
quality: [0.65, 0.90],
speed: 4
},
gifsicle: { // 压缩gif
interlaced: false,
},
webp: { // 将JPG和PNG图像压缩为WEBP
quality: 75
}
}
},
],
}]
复制代码
4. 删除无用 CSS
purgecss-webpack-plugin 和 mini-css-extract-plugin 配合使用
const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PurgecssPlugin = require('purgecss-webpacak-plugin')
const PATHS = {
src:path.join(__dirname,'src')
}
module.exports = {
module:{
rules:[
{
test:/\.css$/,
use:[
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins:[
new MiniCssExtractPlugin({
filename:'[name].css',
}),
new PurgecssPlugin({
paths:glob.sync(`${PATHS.src}/**/*`,{nodir:true})
})
]
}
复制代码
5. 动态 Polyfill
我们希望浏览器能提供一些特性,但是它没有,我们写段代码来实现它,那这段代码可以成为补丁。
我们通常是通过 babel-polyfill.js 来解决这个,但是该库打包后体积比较大。因此我们可以通过动态 polyfill 来处理。
它的原理是:识别浏览器的 User Agent 下发不同的 Polyfill。
<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CArray.prototype.includes"></script>
复制代码
6. 总结
至此完成了 webpack 性能优化相关的学习。
''
评论 (2 条评论)