【Vue3】【笔记】----第九章:Vue3 项目优化与部署(从能跑到能上线)
·
第九章:Vue3 项目优化与部署(从能跑到能上线)
一、入门:项目优化的核心目标与基础认知
项目优化不是“锦上添花”,而是上线前的“必备步骤”——核心目标是减小打包体积(让用户更快下载资源)、提升页面性能(让页面加载/交互更流畅)、增强稳定性(减少线上报错),最终提升用户体验和搜索引擎排名(SEO)。
Vue3 项目的优化主要围绕两大方向:
- 开发阶段优化:编码时规避性能问题(如合理使用
v-if/v-show、避免不必要的响应式); - 构建与部署阶段优化:通过工具链(Vite/Webpack)减小打包体积,通过服务器配置(Nginx)优化资源加载。
二、精通:全方位优化实战(从代码到构建)
1. 代码层面优化(开发时直接落地)
(1)响应式优化:避免不必要的响应式数据
- 问题:用
ref/reactive包裹不需要响应式的数据(如静态配置、临时变量),会增加 Vue 响应式系统的计算开销; - 解决方案:
- 静态数据直接定义为普通变量(无需
ref):// 错误:静态配置不需要响应式 const staticConfig = ref({ pageSize: 10, title: '列表' }) // 正确:普通变量,不触发响应式追踪 const staticConfig = { pageSize: 10, title: '列表' } - 临时变量(如函数内的中间值)不定义为响应式:
const handleCalculate = () => { // 临时变量,无需响应式 const tempNum = 10 return tempNum * count.value // 仅 count 是响应式数据 }
- 静态数据直接定义为普通变量(无需
(2)模板渲染优化:减少不必要的 DOM 操作
-
用
v-show替代v-if(频繁切换场景):v-if:条件不满足时会销毁 DOM,满足时重新创建,适合“一次判断、很少切换”(如权限控制的按钮);v-show:通过display: none隐藏 DOM,DOM 始终存在,适合“频繁切换”(如 Tab 切换、弹窗显示隐藏),避免频繁创建/销毁 DOM 的开销。
-
v-for必须加key且避免用index作为key:key的作用是帮助 Vue 识别 DOM 节点的唯一性,避免复用错误;- 用
index作为key(如列表排序/删除时),会导致 Vue 误判节点身份,引发渲染错乱,推荐用数据的唯一 ID 作为key:<!-- 错误:index 会随列表排序变化 --> <div v-for="(item, index) in list" :key="index">{{ item.name }}</div> <!-- 正确:用数据唯一 ID 作为 key --> <div v-for="item in list" :key="item.id">{{ item.name }}</div>
-
避免在模板中写复杂表达式:复杂逻辑提取到
computed或方法中,提升可读性且computed会缓存结果:<!-- 错误:模板中逻辑复杂,且无缓存 --> <p>{{ item.price > 100 ? `¥${item.price.toFixed(2)}` : `¥${item.price}` }}</p> <!-- 正确:用 computed 缓存结果 --> <p>{{ formatPrice(item.price) }}</p> <script setup> const formatPrice = computed(() => (price) => { return price > 100 ? `¥${price.toFixed(2)}` : `¥${price}` }) </script>
(3)组件优化:拆分与缓存结合
- 拆分大型组件:将超过 300 行代码的组件拆分为“基础组件”(如
InputItem、ButtonGroup)和“业务组件”,提升复用性和维护性,同时减少单个组件的渲染压力; - 合理使用
KeepAlive缓存组件:对“切换后不需要重新渲染”的组件(如列表页、表单页)用KeepAlive缓存,避免重复请求数据和 DOM 渲染(详见第七章),但不要缓存所有组件(如实时更新的仪表盘),避免内存占用过高。
2. 构建层面优化(Vite 配置为主)
Vue3 项目推荐用 Vite 构建(比 Webpack 更快),通过修改vite.config.js实现打包优化。
(1)减小打包体积:Tree Shaking 与按需引入
- Tree Shaking:Vite 默认支持 Tree Shaking(摇树优化),会自动移除代码中“未被使用的部分”(如未调用的函数、未引入的组件),但需确保代码符合 ES 模块规范(避免用
CommonJS的require); - UI 库按需引入:如 Element Plus、Ant Design Vue 等 UI 库,全量引入会增加 100KB+ 体积,需配置按需引入:
- 安装插件:
npm install unplugin-vue-components unplugin-auto-import -D - 修改
vite.config.js:
// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // 按需引入 UI 库的插件 import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ vue(), // 自动导入 Element Plus 的 API(如 ElMessage) AutoImport({ resolvers: [ElementPlusResolver()], }), // 自动导入 Element Plus 的组件(无需手动 import) Components({ resolvers: [ElementPlusResolver()], }), ], })- 使用组件:直接在模板中用
<el-button>,无需手动import ElButton from 'element-plus/es/components/button/index',插件会自动按需引入。
- 安装插件:
(2)资源优化:图片、字体处理
-
图片压缩与格式优化:
- 安装图片压缩插件:
npm install vite-plugin-imagemin -D - 配置插件(自动压缩 png/jpg/svg 等格式):
// vite.config.js import Imagemin from 'vite-plugin-imagemin' export default defineConfig({ plugins: [ // ...其他插件 Imagemin({ gifsicle: { optimizationLevel: 7 }, // gif 压缩 optipng: { optimizationLevel: 7 }, // png 压缩 jpegtran: { quality: 80 }, // jpg 压缩(质量 80,肉眼无明显差异) svgo: { plugins: [{ removeViewBox: false }] }, // svg 压缩 } ] })- 优先使用 WebP 格式:WebP 比 JPG 小 30%+,可通过
<picture>标签兼容旧浏览器:
<picture> <source srcset="image.webp" type="image/webp"> <!-- 支持 WebP 的浏览器加载 --> <img src="image.jpg" alt="示例图片"> <!-- 不支持的浏览器加载 JPG --> </picture> - 安装图片压缩插件:
-
字体文件优化:
- 字体文件(如中文字体)体积大(常超过 1MB),需用“字体子集化”工具(如 FontSpider)提取项目中实际使用的字符,删除无用字符,体积可减小 80%+;
- 配置 Vite 加载字体文件:
// vite.config.js export default defineConfig({ resolve: { alias: { '@fonts': path.resolve(__dirname, 'src/assets/fonts'), // 字体文件路径别名 } } })
(3)构建产物分析:定位大文件
通过rollup-plugin-visualizer插件生成打包体积分析图,直观看到哪些文件体积过大,针对性优化:
- 安装插件:
npm install rollup-plugin-visualizer -D - 配置插件:
// vite.config.js
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
// ...其他插件
visualizer({
open: true, // 构建完成后自动打开分析图
gzipSize: true, // 显示 gzip 压缩后的体积
brotliSize: true, // 显示 brotli 压缩后的体积
})
]
})
- 执行打包:
npm run build,会在项目根目录生成stats.html,打开后可看到:- 如
node_modules/lodash/lodash.js体积大,可替换为lodash-es(支持 Tree Shaking),或只引入需要的函数(如import debounce from 'lodash/debounce'); - 如自定义组件体积大,检查是否包含未使用的代码或大型资源。
- 如
3. 性能优化:提升加载与交互速度
(1)首屏加载优化:预加载与懒加载
-
预加载(Preload):对“首屏必需的资源”(如核心 JS、CSS、字体)用
<link rel="preload">提前加载,避免渲染阻塞:<!-- index.html 中 --> <link rel="preload" href="/src/assets/fonts/main-font.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/src/main.js" as="script"> -
懒加载(Lazy Load):
- 路由懒加载:已在第六章讲解,通过动态
import实现“访问路由时才加载组件”; - 图片懒加载:用
vue-lazyload插件实现“图片进入视口时才加载”:- 安装插件:
npm install vue-lazyload -S - 全局注册:
// main.js import { createApp } from 'vue' import VueLazyload from 'vue-lazyload' const app = createApp(App) app.use(VueLazyload, { loading: '/src/assets/loading.png', // 加载中占位图 error: '/src/assets/error.png' // 加载失败占位图 })- 使用:将
<img src>改为<img v-lazy>:
<img v-lazy="item.imageUrl" alt="商品图片"> - 安装插件:
- 路由懒加载:已在第六章讲解,通过动态
(2)缓存策略:减少重复下载
- HTTP 缓存:通过 Nginx 配置
Cache-Control,让浏览器缓存静态资源(如 JS、CSS、图片),下次访问无需重新下载:# Nginx 配置 location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff2)$ { expires 7d; # 缓存 7 天 add_header Cache-Control "public, max-age=604800"; # 604800 秒 = 7 天 } - 内容哈希(Content Hash):Vite 打包时会自动为静态资源添加“内容哈希”(如
main.[hash].js),当文件内容变化时,哈希值会变,浏览器会重新下载;内容不变时,哈希值不变,浏览器继续使用缓存,避免“缓存过期”问题。
三、实战:项目部署(Nginx 上线流程)
Vue3 项目是单页应用(SPA),部署时需解决“路由刷新404”“资源访问路径”两个核心问题,推荐用 Nginx 作为服务器。
1. 打包项目:生成部署文件
- 配置
vite.config.js的base(资源基础路径):- 若项目部署在域名根路径(如
https://example.com/),base: '/'(默认); - 若部署在子路径(如
https://example.com/vue-project/),base: '/vue-project/':// vite.config.js export default defineConfig({ base: '/vue-project/', // 根据实际部署路径修改 // ...其他配置 })
- 若项目部署在域名根路径(如
- 执行打包命令:
npm run build,会在项目根目录生成dist文件夹(部署的核心文件)。
2. Nginx 配置:解决 SPA 问题
- 安装 Nginx:根据操作系统(Windows/Linux/Mac)下载安装,Linux 可通过
yum install nginx(CentOS)或apt install nginx(Ubuntu)安装。 - 上传
dist文件夹:将dist文件夹上传到 Nginx 的html目录(如 Linux 路径/usr/share/nginx/html/vue-project)。 - 修改 Nginx 配置文件(核心步骤):
- 找到配置文件路径:Linux 通常在
/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf; - 编辑配置:
server { listen 80; # 监听 80 端口(HTTP) server_name example.com; # 你的域名(如无域名,填服务器 IP) # 配置项目路径 location /vue-project/ { # 与 vite.config.js 的 base 一致 root /usr/share/nginx/html; # Nginx 静态文件根目录 index index.html; # 默认首页 try_files $uri $uri/ /vue-project/index.html; # 解决 SPA 路由刷新404 # 解释:当访问 /vue-project/goods/1 时,Nginx 先找对应文件,找不到则返回 index.html,由 Vue Router 处理路由 } # 静态资源缓存配置(优化加载速度) location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff2)$ { root /usr/share/nginx/html; expires 7d; add_header Cache-Control "public, max-age=604800"; } }
- 找到配置文件路径:Linux 通常在
- 重启 Nginx:
- Linux:
systemctl restart nginx; - Windows:打开 Nginx 安装目录,执行
nginx -s reload。
- Linux:
- 验证部署:在浏览器输入
https://example.com/vue-project/(或服务器 IP + 路径),能正常访问项目且路由刷新不报错,说明部署成功。
3. 进阶:HTTPS 配置(提升安全性)
现在主流网站都用 HTTPS,需申请 SSL 证书(免费证书可在阿里云、腾讯云申请),并修改 Nginx 配置:
server {
listen 443 ssl; # 监听 443 端口(HTTPS)
server_name example.com;
# SSL 证书配置(替换为你的证书路径)
ssl_certificate /etc/nginx/ssl/example.com.pem; # 证书公钥
ssl_certificate_key /etc/nginx/ssl/example.com.key; # 证书私钥
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3; # 支持的 TLS 版本
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
# 项目路径配置(与 HTTP 一致)
location /vue-project/ {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /vue-project/index.html;
}
}
# HTTP 重定向到 HTTPS(强制使用 HTTPS)
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri; # 将 HTTP 请求重定向到 HTTPS
}
更多推荐
所有评论(0)