优化
想要优化的话要看是哪一步出现了问题
分析工具
1. speed-measure-webpack-plugin 分析打包的速度
1.1 安装
pnpm install speed-measure-webpack-plugin -D
1.2 在vue.config.js中修改配置
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({}),
});
1.3 执行命令
npm run build
看到SMP 就成功了
2. webpack-bundle-analyzer 分析打包后的文件体积大小
2.1 安装
pnpm i webpack-bundle-analyzer -D
2.2 在plugins中配置
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
plugins: [
new BundleAnalyzerPlugin()
]
}),
});
打包之后就能看到结果
3. 缩小范围
3.1 extension
配置resolve中的extension可以缩小文件的查找范围,在require或者是import的时候不需要写扩展名,会自动进行查找
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
resolve: {
extensions: ['.js', '.vue', 'ts', 'json', 'jsx']
},
plugins: [
new BundleAnalyzerPlugin()
]
}),
});
3.2 设置别名可以加快webpack的查找速度
就是直接给一个路径解析,而不是让webpack自己去查找,加快了速度
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
resolve: {
extensions: ['.js', '.vue', 'ts', 'json', 'jsx'],
alias: {
'@': join(__dirname, 'src'),
'assets': join(__dirname, 'src/assets')
}
},
plugins: [
new BundleAnalyzerPlugin()
]
}),
});
3.3 modules
-
告诉webpack在解析模块的时候搜索哪些目录,可以使用相对路径和绝对路径.
-
相对路径的扫描方式与Node扫描node_modules的方式类似,都是通过当前目录及其祖先就是(./node_modules. ../node_modules等)进行扫描,
-
绝对路径的话,只会在指定目录中查找
-
一般不需要配置,当你的项目中有指定的目录让webpack找的话,就可以配置。默认是找node_modules
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { join } = require('path')
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
resolve: {
extensions: ['.js', '.vue', 'ts', 'json', 'jsx'],
alias: {
'@': join(__dirname, 'src'),
'assets': join(__dirname, 'src/assets')
},
// 默认就是node_modules 不需要配置。有需求才配置 这里只是知道有这个知识点
modules: ['node_modules']
},
plugins: [
new BundleAnalyzerPlugin()
]
}),
});
4. compression-webpack-plugin 压缩插件
4.1 安装
pnpm add -D compression-webpack-plugin
4.2 属性
| 名称 | 默认值 | 描述 |
|---|---|---|
| test | undefined | 匹配哪些后缀的文件 |
| include | undefined | 符合条件的所有资源 |
| exclude | undefined | 排除负荷条件的资源 |
| algorithm | gzip | 事实上就是zlib |
| compressionOptions | ||
| threshold | 0 | 文件大小超过多少才压缩 |
| minRatio | 0.8 | 压缩大小/原始大小 小于等于设置的比例 |
| filename | "[path][base].gz” | 文件名 |
| deleteOriginalAssets | false | 是否删除dist中原始的资源 |
4.3 配置
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const CompressionPlugin = require("compression-webpack-plugin");
const { join } = require("path");
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
resolve: {
extensions: [".js", ".vue", "ts", "json", "jsx"],
alias: {
"@": join(__dirname, "src"),
assets: join(__dirname, "src/assets"),
},
modules: ["node_modules"],
},
plugins: [
new BundleAnalyzerPlugin(),
new CompressionPlugin({
test: /\.(vue|js|ts|json|css)$/, // 什么文件需要压缩
exclude: "node_modules", // 排除什么
algorithm: "gzip", // 默认是gzip 其实是node那个模块zlib
threshold: 90, // 文件大小超过多少会被压缩
minRatio: 0.8, // 压缩大小/当前大小-> 小于0.8才会被处理 默认0.8
filename(pathData) {
if (/\.(png|svg|jpg)$/.test(pathData.filename)) {
return "assets/svg/[path][base].gz";
}
return "[path][base].gz";
}
}),
],
}),
});
可以看到压缩的效果还是可以的
虽然压缩了但是在服务器上怎么访问呢 打包后的文件都是.gz结尾的,怎么处理呢?于是我把文件放在了nginx的html目录下
修改了代理配置
vi /etc/nginx/nginx.conf
加了这个属性 就能直接访问了
就正常返回了
5. terser-webpack-plugin 多进程打包
- 并发次数 os.cpus().length - 1
5.1 安装
pnpm add -D terser-webpack-plugin
5.2 选项
| 名称 | 默认值 | 描述 |
|---|---|---|
| test | undefined | 匹配哪些后缀的文件 |
| include | undefined | 符合条件的所有资源 |
| exclude | undefined | 排除负荷条件的资源 |
| algorithm | gzip | 事实上就是zlib |
| compressionOptions | {} | |
| threshold | 0 | 文件大小超过多少才压缩 |
| minRatio | 0.8 | 压缩大小/原始大小 小于等于设置的比例 |
| filename | "[path][base].gz” | 文件名 |
| deleteOriginalAssets | false | 是否删除dist中原始的资源 |
5.3 配置
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const CompressionPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const { join } = require("path");
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
...
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {},
}),
],
},
}),
});
6.sourcemap
- 一般情况下,我们不希望任何人都可以在浏览器中直接能看到我们未编译的源码,所以我们不希望提供sourceMap, 但是我们需要sorceMap来定义我们的错误信息
- 设置hidden-source-map
- 一方面webpack会生成sourcemap文件以提供给错误收集工具比如sentry,另一方面又不会为 bundle 添加引用注释,以避免浏览器使用
7. 将通用的三方库打包成vendor
- 他们的体积是不会变化的
- 所以可以利用缓存 只是开发环境
- 生产环境不用这个缓存
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: smp.wrap({
...
entry: {
vendor: ['element-plus']
},
...
}),
});
8. image-webpack-loader 压缩图片
- 关于图片的处理,要让UI给出压缩后的图片.
- 相同的图片质量,webp格式的图片比较小.
- 压缩图片jpg,webp这种像首页的背景图这种通过image-webpack-loader压缩.
- 项目中的svg图片很多要考虑做成雪碧图当成组件来引用,并且也是可以压缩的.
const { defineConfig } = require("@vue/cli-service");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const CompressionPlugin = require("compression-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const { join } = require("path");
const smp = new SpeedMeasurePlugin();
module.exports = defineConfig({
transpileDependencies: true,
publicPath: '.', // 打包出来的index.html中引入的js,css不会出现找不到问题
configureWebpack: smp.wrap({
devtool: "hidden-source-map",
entry: {
vendor: ["element-plus"],
},
output: {
assetModuleFilename: 'assets/[name][ext]'
},
resolve: {
extensions: [".js", ".vue", ".ts", ".json", ".jsx"],
alias: {
"@": join(__dirname, "src"),
assets: join(__dirname, "src/assets"),
},
modules: ["node_modules"],
},
module: {
rules: [
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
"file-loader",
{
loader: "image-webpack-loader",
options: {
mozjpeg: {
progressive: true,
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.9],
speed: 4,
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75,
},
},
},
],
},
],
},
...
}),
});
看了issue,推荐用image-minimizer-webpack-plugin这个loader