图片的加载包含了图片的请求和渲染
比方说当我们开发一个有很多图片的长网页时,一般先加载出现在视口内的几张图片,当滚动条滚动到相应图片的位置时再去加载别的图片
方法一 v-if,如果达到了展示区域,则展示
<template>
<div ref="imageContainer" v-if="isInViewport">
<img :src="imageSrc" alt="Lazy Loaded Image">
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const isInViewport = ref(false);
const imageSrc = ref('图片地址');
const imageContainer = ref(null);
// 检查图片容器是否在视口内的方法
const checkInView = () => {
if (imageContainer.value) {
// 获取图片容器的边界矩形
const rect = imageContainer.value.getBoundingClientRect();
// 如果图片容器的顶部在视口内,并且底部也在视口内,则设置为 true
if (rect.top < window.innerHeight && rect.bottom > 0) {
isInViewport.value = true;
}
}
};
onMounted(() => {
// 初始化检查
checkInView();
// 监听滚动事件,滚动时检查
window.addEventListener('scroll', checkInView);
});
</script>
方法二 使用data-xxx属性,把图片的连接复制给该属性,当达到该区域时,获取该该属性中的图片链接,并把该链接复制给src属性。
原理:
1.存储图片的真实路径,把图片的真实路径绑定给一个以data开头的自定义属性data-src即可,页面中的img元素,如果没有src属性,浏览器就不会发出请求去下载图片(没有请求就提高了性能)
2.需要一个滚动事件,判断元素是否在浏览器窗口,一旦进入视口才进行加载,当滚动加载的时候,就把这张图片替换为真正的url地址(也就是data-src里保存的值)
3.等到图片进入视口后,利用js提取data-src的真实图片地址赋值给src属性,就会去发送请求加载图片,真正实现了按需加载
如果发生滚动事件,会产生大量的循环和判断操作判断图片是否可视区里,因此需要用节流进行优化。
节流方法
// 节流
const throttle = (fn: { apply: (arg0: any, arg1: any[]) => void }, t: number) => {
let flag = true;
const interval = t || 500;
return function (this: any, ...args: any) {
if (flag) {
fn.apply(this, args);
flag = false;
setTimeout(() => {
flag = true;
}, interval);
}
};
};
<template>
<img :data-src="imageSrc" ref="lazyImage" alt="Lazy Loaded Image">
</template>
<script setup>
import { ref, onMounted } from 'vue';
const imageSrc = ref('图片地址');
const lazyImage = ref(null);
// 懒加载方法
const lazyLoad = () => {
if (lazyImage.value) {
// 获取图片容器的边界矩形
const rect = lazyImage.value.getBoundingClientRect();
// 如果图片容器的顶部在视口内,并且底部也在视口内,则加载图片
if (rect.top < window.innerHeight && rect.bottom > 0 && !lazyImage.value.src) {
lazyImage.value.src = lazyImage.value.dataset.src;
lazyImage.value.removeAttribute('data-src');
}
}
};
onMounted(() => {
// 初始化懒加载
lazyLoad();
// 监听滚动事件,滚动时执行懒加载
window.addEventListener('scroll',throttle(lazyLoad, 500), true);
});
</script>
注意
1.挂载时需要立刻调用lazyLoad函数,不然首屏不会加载;若需要图片分页,切换分页后不会也主动加载,需要调用lazyLoad方法
2.同样需要给图片设置key值,不然分页图片不刷新