性能指标
性能的指标,浏览器的控制台中 网络(network) 和 性能(performance)。
network,请求次数越少,DOMContentLoaded(html 被完全解析和加载,不包含样式图片和框架的加载时间),load 越小,性能越好。
performance,fp 第一次看到白屏的时间。fcp 从开始加载到页面的任何一个内容在页面上渲染的时间。lcp 页面可视区域内最大的一块区域完全加载完的时间。
当然,以上分析比较复杂,我们可以使用一个插件 lighthouse 来评估性能。
优化方案
- 数据懒加载处理方案
- 图片懒加载处理方案
- webpack 打包体积过大与CDN 优化处理方案
- 其他优化方案(gzip、http 缓存、service worker)
数据懒加载
当需要展示的数据进入视口时,才向后端发送请求,IntersectionObserver - Web API | MDN (mozilla.org)。
<div class="box" ref="box3Target">
<div class="title">{{ data03.title }}</div>
<ul class="list">
<li class="item" v-for="item in data03.list" :key="item.id">
<img class="item-img" :src="item.img" alt="" />
<div class="item-name">{{ item.name }}</div>
<div class="item-desc">{{ item.desc }}</div>
</li>
</ul>
</div>
onMounted(() => {
const intersectionObserver = new IntersectionObserver((entries) => {
// 当 intersectionRatio 为 0 时,目标在视野外
if (entries[0].intersectionRatio <= 0) {
return console.log('当前视图不可见')
}
console.log('当前视图可见')
})
// 开始监听
intersectionObserver.observe(box3Target.value)
})
VueUse 里面已经对此进行了封装:useIntersectionObserver | VueUse
import { useIntersectionObserver } from '@vueuse/core'
const { stop } = useIntersectionObserver(
// 注意,这里没有 .value
box3Target,
([{ isIntersecting }]) => {
if (isIntersecting) {
console.log('视图可见')
// 获取数据
loadData03()
// 触发 stop 监听停止
stop()
} else {
console.log('视图不可见')
}
}
)
图片懒加载
img 标签非常多,不可能通过把每个 img 标签的 dom 对象都获取到。所以我们可以使用 自定义指令。为需要懒加载的图片加上我们的自定义指令。
directive/index.js
import { useIntersectionObserver } from '@vueuse/core'
const imgLazy = {
mounted(el) {
// console.log(el)
// 图片懒加载:一开始不加载,等到将要看到时在加载
// 1. 缓存当前的图片路径
const catchSrc = el.src
console.log(catchSrc)
// 2. 把 img.src 变为占位图
el.src = 'https://res.lgdsunday.club/img-load.png'
// 3. 监听将要看到
const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
if (isIntersecting) {
// 4. 渲染图片
el.src = catchSrc
// 5. 停止监听
stop()
}
})
}
}
export default {
// app.use 的方式使用
install: (app) => {
app.directive('imgLazy', imgLazy)
}
}
<img v-imgLazy class="img" :src="item.path" alt="" srcset="" />
main.js
import directive from '@/directive'
app.use(directive)
打包优化
不论是使用 webpack 还是 vite ,打包后进行打包分析,针对于特别大的包,我们可以采用
- 排除依赖打包的方法使其在 build 时不打包
- 然后通过 cdn 引入所需的包。
但是要注意,cdn 只能增加用户访问的速度,但是不会减少依赖包的体积。
webpack 和 vite 都会有自己的 cdn 优化方案。
其他
- gzip 压缩
代码中重复度越高,可压缩的空间就越大。当Nginx返回js文件的时候,会判断是否开启gzip,然后压缩后再返回给浏览器。
该压缩方法需要Nginx配置开启Gzip压缩,单纯前端通过webpack插件开启Gzip压缩是不能达到优化效果的。
- http 缓存
一般来说,304 缓存的处理是服务框架中自动进行处理,不需要过多关注。
- service worker
对网站提供离线体验。使用并不广泛。