图片懒加载是一种延迟加载图片的技术,当用户滚动页面时,只有当图片进入可视区域时才会加载,从而提高页面加载速度和性能。
实现图片懒加载的方法有多种,其中比较常用的是使用 JavaScript 监听滚动事件,判断图片是否进入可视区域,然后动态加载图片。以下是一个简单的实现示例:
<img data-src="image.jpg" class="lazyload" />
<script>
const images = document.querySelectorAll('.lazyload');
function lazyload() {
images.forEach((image) => {
const rect = image.getBoundingClientRect();
if (rect.top >= 0 && rect.bottom <= window.innerHeight) {
image.src = image.dataset.src;
image.classList.remove('lazyload');
}
});
}
window.addEventListener('scroll', lazyload);
window.addEventListener('resize', lazyload);
window.addEventListener('orientationchange', lazyload);
script>
上述代码中,我们首先将需要懒加载的图片添加一个 data-src
属性,用于存储图片的真实地址。然后使用 getBoundingClientRect()
方法获取图片相对于视口的位置信息,判断图片是否进入可视区域。如果图片进入可视区域,则将 data-src
属性的值赋给 src
属性,从而加载图片。
Vue3中实现自定义图片懒加载插件可以使用Vue3提供的自定义指令来实现。
首先,我们需要在项目中安装Intersection Observer
库,它是用来监听元素是否进入视口的库。
npm install intersection-observer
然后,我们可以创建一个lazyload
指令,代码如下:
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('lazyload', {
beforeMount(el, binding) {
let options = {
rootMargin: '0px',
threshold: 0.1
}
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
el.src = binding.value
observer.unobserve(el)
}
})
}, options)
observer.observe(el)
}
})
app.mount('#app')
在上面的代码中,我们创建了一个名为lazyload
的指令,它会在元素进入视口时将src
属性设置为指令的值,即图片的地址。我们使用IntersectionObserver
来监听元素是否进入视口,当元素进入视口时,我们将src
属性设置为指令的值,并停止监听该元素。
最后,我们可以在模板中使用v-lazyload
指令来实现图片懒加载,代码如下:
<template>
<img v-lazyload="imageUrl" alt="image">
template>
在上面的代码中,我们将图片的地址绑定到v-lazyload
指令上,当图片进入视口时,src
属性会被设置为图片的地址,从而实现了图片懒加载的效果。
为了进一步优化性能,我们可以使用以下技巧:
使用占位符:在图片未加载完成前,可以使用一个占位符(比如一个 loading 图片)来占据图片的位置,从而避免页面布局的抖动。
批量加载:当用户滚动页面时,可能会触发大量的图片加载请求,从而影响页面性能。为了避免这种情况,可以将需要加载的图片分批加载,比如每次只加载 5 张图片。
预加载:对于一些重要的图片,可以在页面加载完成后立即加载,从而提高用户体验。
在Vue3中实现图片懒加载的性能优化,可以使用Intersection Observer API,它可以监听元素是否进入了可视区域,从而实现图片的懒加载。
具体实现步骤如下:
在组件中使用ref
获取需要懒加载的图片元素。
在setup
函数中使用onMounted
钩子函数,创建一个IntersectionObserver
实例,并将其绑定到图片元素上。
在IntersectionObserver
的回调函数中,判断图片是否进入了可视区域,如果是,则将图片的src
属性设置为真实的图片地址。
代码示例:
<template>
<div>
<img ref="img" data-src="lazy-image.jpg" />
div>
template>
<script>
import { onMounted, ref } from 'vue';
export default {
setup() {
const imgRef = ref(null);
onMounted(() => {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
observer.unobserve(lazyImage);
}
});
});
observer.observe(imgRef.value);
});
return {
imgRef,
};
},
};
script>
在上面的代码中,我们使用ref
获取了图片元素,并在onMounted
钩子函数中创建了一个IntersectionObserver
实例,将其绑定到图片元素上。在IntersectionObserver
的回调函数中,判断图片是否进入了可视区域,如果是,则将图片的src
属性设置为真实的图片地址,并停止观察该图片元素。
这样就可以实现图片懒加载的性能优化了。
getBoundingClientRect()方法:该方法返回元素的大小及其相对于视口的位置。通过判断元素的位置和大小,可以判断元素是否在可视化区域。
Intersection Observer API:该API可以观察元素与其祖先元素或顶级文档视窗的交叉状态。通过监听元素与视窗的交叉状态,可以判断元素是否在可视化区域。
scroll事件:通过监听滚动事件,可以获取视窗的滚动位置,从而计算出元素的位置,判断元素是否在可视化区域。
常用的方法:
获取图片元素的位置信息,包括元素距离页面顶部的距离和元素高度。
获取页面可视化区域的高度和滚动距离。
判断图片元素距离页面顶部的距离是否小于页面可视化区域的高度加上滚动距离,如果是,则表示图片元素已经进入可视化区域。