前言
3年前端经验,主要技术栈Vue2/Vue3,准备被裁失业,好久没刷面试经验,现在又可以重新捡起来了,顺便记录一下最近学习的面试知识点,方便了解和学习。
Vue性能优化
Vue 项目的性能优化我一般会从几个方面考虑,包括首屏加载优化、组件渲染优化、打包体积优化、网络请求优化,以及用户交互体验优化。
首屏加载优化
路由懒加载
bash
const Home = () => import('@/views/Home.vue');
按需加载,减少首包体积
分包 / Tree Shaking
Vite / webpack:在工程化项目中,Vite / webpack会自动 Tree Shaking删除未使用代码
避免一次加载整个组件库
为什么有时候会加载整个组件库:如果使用import _ from 'lodash',引入全部就会加载组件库,import debounce from 'lodash/debounce'或者import { debounce } from 'lodash-es'按需引入就不会
CDN 加速
比如:Vue,ECharts,lodash,放 CDN,可以减少打包体积,因为像element-plus、lodash体积都很大,如果包含element-plus、lodash的项目打包出来的app.js有5M,浏览器在执行的时候
bash
先下载 5MB
↓
再解析
↓
再执行
↓
页面才能显示如果配置CDN,通过
`
`去加载,这样打包出来的app.js只会有500k左右的大小,而且还有有缓存,不用重复加载,所以使用CDN首屏加载更快
图片优化
WebP:是 Google 推出的图片格式。同样画质,体积更小
懒加载:图片进入可视区域时才加载。<img src="a.jpg" loading="lazy">,压缩:构建时压缩,vite-plugin-imagemin,在npm run build的时候执行
bash
import viteImagemin from 'vite-plugin-imagemin'//引入图片压缩插件
viteImagemin({
mozjpeg: {//JPEG 图片压缩器
quality: 70//压缩质量为70
}
})
为什么首屏加载的时候要优化图片,现在的图片一般都很大,图片往往占页面资源的大部分。所以图片优化 = 前端性能优化核心,
渲染优化
v-if 和 v-show 区别
v-if :真正销毁 DOM适合低频切换
v-show:display:none,适合高频切换
key 的合理使用
bash
<div v-for="item in list" :key="item.id">
作用:提高 diff 效率,避免错误复用 DOM
computed 缓存
bash
const total = computed(() => ...)
computed:有缓存,methods:每次都会执行
组件优化
keep-alive
bash
<keep-alive>
<router-view />
</keep-alive>
keep-alive:缓存组件实例,避免组件反复销毁和重新创建。适用场景:列表返回详情,Tab 页面
大列表优化
**虚拟列表:**只渲染可视区域,一般都用现成的,vue-virtual-scroller、或者Element Plus自带的el-auto-resizer进行实现
实现原理:
bash
<div class="container" @scroll="onScroll">
<div class="phantom" :style="{ height: totalHeight + 'px' }"></div>
<div
class="list"
:style="{ transform: `translateY(${offsetY}px)` }"
>
<div
v-for="item in visibleData"
:key="item.id"
class="item"
>
{{ item.text }}
</div>
</div>
</div>
const totalHeight = list.length * itemHeight
const itemHeight = 50
const visibleCount = 10
const startIndex = Math.floor(scrollTop / itemHeight)
const visibleData = list.slice(
startIndex,
startIndex + visibleCount
)
const offsetY = startIndex * itemHeight
网络优化
防抖 / 节流
请求缓存
比如:localStorage、sessionStorage、Pinia 持久化
并发控制
避免Promise.all 一次几十个请求
使用接口进行分页
浏览器层优化
用transform、opacity代替left、top,因为top、left 会触发页面的重排(Reflow),而transform、opacity会触发页面的重绘,消耗性能少一些
项目里怎么讲
在项目中我们做过几个性能优化:
- 路由使用动态 import 做懒加载,减少首屏体积
- 对大列表使用虚拟滚动,避免一次渲染几千条数据
- 搜索框使用debounce,减少接口请求
- 使用 keep-alive 缓存页面状态
- 对一些大对象避免深度 reactive,减少响应式开销
- 使用 transform 优化动画,减少回流