vite 优化
vite项目性能优化
1、vite的构建速度
从npm run dev 命令开始到页面展示的速度
2、页面性能指标
- 首屏时间
- 白屏时间
- 首次输入延迟
- 首次交互时间
- 页面加载时间
- 页面渲染时间
- 页面回流次数
- 页面重绘次数
- 页面元素数量
- 页面元素大小
- 页面元素数量
- 页面元素大小
- ......
3、js逻辑优化
- 减少代码的副作用
- 减少循环次数
- 减少事件绑定
- 减少dom操作
- 减少css操作
- 减少计算
- 减少异步请求
- 减少promise
- 减少递归
- 减少闭包
- 减少内存占用
- 减少内存分配
- 减少内存回收
- 减少内存泄漏
- 减少内存泄漏
- ......
4、css优化
- 关注继承属性:能继承的旧不要重复写
- 尽量避免太过于深的css嵌套
- ......
5、构建优化
减小构建文件的大小
- 压缩
treeshaking
- 图片资源压缩
- cdn加载
- 分包
- ......
分包策略
1. 什么是分包?
将业务代码和公共代码(依赖)进行单独打包到不同的包中,
2、分包配置
在 package.json
中配置 build
字段,如下:
export default defineConfig(() => {
return {
build: {
rollupOptions: {
output: {
assetFileNames: "[name].[hash].[ext]",
},
// 静态资源目录
assetsDir: "assets",
// 按照依赖进行分包
// manualChunks: {
// vue: ["vue"],
// element: ["element-plus"],
// pinia: ["pinia"],
// vueRouter: ["vue-router"],
// },
// 把所有依赖都打包到同一个文件当中
manualChunks(id) {
if (id.includes("node_modules")) {
return "vendor";
}
},
},
}
}
})
Gzip压缩
为什么要进行gzip压缩
在前面配置了分包策略之后,再次进行打包,如果项目当中安装了很多的依赖,公共依赖包vendor还是会很大,但是在build的时候可以发现有一个gzip压缩的插件,可以将依赖包进行压缩,减少打包后的体积。
dist/index.html 0.70 kB │ gzip: 0.40 kB
dist/index.3e1c17ba.css 7.79 kB │ gzip: 2.33 kB
dist/vendor.0fe5958d.css 379.29 kB │ gzip: 53.56 kB
dist/assets/index-1999f5a6.js 78.34 kB │ gzip: 19.32 kB
dist/assets/vendor-f5c4bb20.js 1,908.62 kB │ gzip: 573.20 kB
此时dist目录的大小为13,7M
进行gzip压缩
npm i vite-plugin-compression -D
在vite.config.js文件中进行配置
import viteCompression from 'vite-plugin-compression'
export default defineConfig(() => {
return {
plugins: [
viteCompression()
]
}
})
打包之后会生成对应的gzip文件 。但是在浏览器中获取gzip文件的时候,需要在请求的时候加上.gz后缀,否则浏览器会直接请求原始文件。 并且浏览器解压时也需要一定的时间,所以在文件不是很大的时候,使用gzip压缩会降低性能,所以需要根据项目情况进行配置。
dist/路径....../index.3e1c17ba.css.gz 7.60kb / gzip: 2.27kb
dist/路径....../assets/index-1999f5a6.js.gz 77.58kb / gzip: 18.59kb
dist/路径....../vendor.0fe5958d.css.gz 370.41kb / gzip: 51.89kb
dist/路径....../assets/vendor-f5c4bb20.js.gz 1864.70kb / gzip: 558.58kb
动态导入
路由懒加载的实现方式通常是使用动态导入(Dynamic Import)语法,比如在 Vue 项目中使用 import() 来导入需要懒加载的组件。当用户访问到对应的路由时,该组件才会被异步加载,实现了按需加载的效果。
直接导入
在使用router路由的时候我这有一个大的页面,用到了mapbox,而后我在首页刷新页面
const router = [{
path: "/mapBox",
name: mapBox,
component: mapBox,
chinaName: 'MapBox地图页面入口'
}]
我这个首页就是一个简单的hello world,但是他还是会请求我这个mapbox页面相关的资源,如下请求:
而且这里获取依赖当中的js,耗时较长,就会导致一个简单的页面也要等待那么长时间才能渲染出来
耗时2.44 http://localhost:3000/src/components/mapBox.vue
耗时20.09 http://localhost:3000/node_modules/.vite/deps/mapbox-gl.js?v=21874b81
耗时1.04 http://localhost:3000/node_modules/mapbox-gl/dist/mapbox-gl.css
动态导入
在使用动态导入的时候,当用户访问到对应的路由时,该组件才会被异步加载,实现了按需加载的效果。而不会在每个页面都去获取这个mapbox的js资源耗费很长的时间
const router = [{
path: "/mapBox",
name: 'mapBox',
component: () => import('@/components/mapBox.vue'),
chinaName: 'MapBox地图页面入口'
}]
CDN 内容分发网络
为什么要做CDN
将我们依赖的第三方模块全部写成cdn的形式,然后保证我们自己代码的一个小体积(体积小服务器和客户端的传输压力就没那么大
使用CDN打包
在前面我们不做CDN打包的时候,可以先打个包观察大小(这里使用了分包策略)
dist/index.html 0.70 kB │ gzip: 0.40 kB
dist/index.3e1c17ba.css 7.79 kB │ gzip: 2.33 kB
dist/vendor.0fe5958d.css 379.29 kB │ gzip: 53.56 kB
dist/assets/index-1999f5a6.js 78.34 kB │ gzip: 19.32 kB
dist/assets/vendor-f5c4bb20.js 1,908.62 kB │ gzip: 573.20 kB
安装插件
npm i vite-plugin-cdn-import -D
使用插件
这里把vue-router
、pinia
、element-plus
都打包成cdn。这里主要是element会占用部分体积,给其加上cdn配置后,再次打包可以看到打包大小会减小
export default defineConfig(() => {
return {
plugins: [
viteCDNPlugin({
modules: [
{
name: "vue-router",
var: "VueRouter",
path: "https://cdn.jsdelivr.net/npm/vue-router@4.2.5/dist/vue-router.global.min.js",
},
{
name: "pinia",
var: "Pinia",
path: "https://cdn.jsdelivr.net/npm/pinia@2.1.6/dist/pinia.iife.min.js",
},
{
name: 'element-plus',
var: 'ElementPlus',
path: 'https://cdn.jsdelivr.net/npm/element-plus@1.0.2-beta.31/dist/index.js',
css: 'https://cdn.jsdelivr.net/npm/element-plus@1.0.2-beta.31/dist/index.css'
}
]
}),
],
}
})
进行打包对比
dist/index.html 1.08 kB │ gzip: 0.51 kB
dist/index.3e1c17ba.css 7.79 kB │ gzip: 2.33 kB
dist/vendor.0fe5958d.css 379.29 kB │ gzip: 53.56 kB
dist/assets/index-a5a49024.js 78.40 kB │ gzip: 19.35 kB
dist/assets/vendor-7a7abc79.js 1,069.89 kB │ gzip: 305.32 kB
剔除console和debugger
默认打包
dist/index.html 1.08 kB │ gzip: 0.51 kB
dist/index.3e1c17ba.css 7.79 kB │ gzip: 2.33 kB
dist/vendor.b7ad724d.css 379.29 kB │ gzip: 53.67 kB
dist/assets/fit-b4bf838a.js 0.52 kB │ gzip: 0.29 kB
dist/assets/driver-page-0549775d.js 1.01 kB │ gzip: 0.63 kB
dist/assets/index-4fcd8145.js 38.25 kB │ gzip: 10.08 kB
dist/assets/cesium-d7bf557c.js 40.14 kB │ gzip: 8.98 kB
dist/assets/vendor-93cdb6d1.js 1,069.89 kB │ gzip: 305.32 kB
安装依赖
npm i terser -D
添加配置
export default defineConfig(() => {
return {
build: {
minify: "terser",
terserOptions: {
compress: {
//生产环境时移除console
drop_console: true,
drop_debugger: true,
},
}
}
}
})
对比打包大小
dist/index.html 1.08 kB │ gzip: 0.51 kB
dist/index.3e1c17ba.css 7.79 kB │ gzip: 2.33 kB
dist/vendor.b7ad724d.css 379.29 kB │ gzip: 53.67 kB
dist/assets/fit-8efb0931.js 0.51 kB │ gzip: 0.29 kB
dist/assets/driver-page-b9ab23c8.js 1.00 kB │ gzip: 0.63 kB
dist/assets/index-7b1acea1.js 37.69 kB │ gzip: 9.73 kB
dist/assets/cesium-cd8d8d50.js 40.06 kB │ gzip: 8.95 kB
dist/assets/vendor-6cccd9b5.js 1,056.34 kB │ gzip: 293.94 kB