一、引言
在现代 Web 开发领域,图片懒加载的重要性不容小觑。
首先,它对页面加载速度有着极大提升作用。当页面包含大量图片时,若不采用懒加载,所有图片会在页面初始化时一同请求加载,这会导致加载时间过长。而懒加载仅在图片进入浏览器可视区域时才触发加载,大大减少了初始加载的数据量,使关键资源(如 HTML、CSS 等)能优先高效加载,让用户更快看到页面布局并进行交互。
其次,能有效节省用户流量。对于移动用户或流量有限的情况,懒加载按需加载图片,避免了加载那些用户可能根本不会看到的图片,防止不必要的流量消耗。
二、图片懒加载原理概述
简单解释什么是图片懒加载。即图片在进入浏览器的可视区域时才进行加载,而不是在页面初始化时就全部加载所有图片。
可以用一些简单的示意图或者类比的方式(比如把页面想象成一个画展,只有当观众走到画作前才会仔细去看这幅画,也就是才加载这幅画的细节,类似图片进入可视区才加载)来帮助读者更好地理解懒加载的概念。
三、封装图片懒加载 Hooks 的步骤
在这里我们提供啦两个方式一种是原生封装Hooks函数,另一种是使用vue3-lazyload库来实现图片懒加
首先我们需要在src下创建一个hooks文件夹,在文件夹下新建一个useLazyLoad.js
-
原生Hooks封装
-
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'; export default function useLazyLoad() { // 用于存储图片是否加载完成的响应式状态 const isLoaded = ref(false); // 加载图片的函数 const loadImage = (imgElement) => { if (!imgElement) return; const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; isLoaded.value = true; observer.disconnect(); } }); }); observer.observe(imgElement); }; // 在组件挂载时执行的逻辑 onMounted(() => { // 使用nextTick确保DOM更新完成后再获取图片元素 nextTick(() => { const imgElements = document.querySelectorAll('img[data-src]'); imgElements.forEach((img) => { loadImage(img); }); }); }); // 在组件卸载前执行的逻辑 onBeforeUnmount(() => { const observers = []; const imgElements = document.querySelectorAll('img[data-src]'); imgElements.forEach((img) => { const observer = img.__observer; if (observer) { observers.push(observer); } }); observers.forEach((observer) => { observer.disconnect(); }); }); return { isLoaded }; }
isLoaded
是一个响应式引用,用于跟踪图片是否已经加载完成。loadImage
函数创建了一个IntersectionObserver
实例来观察图片是否进入浏览器的可视区域。当图片进入可视区域时,将图片的src
属性设置为预先存储在data-src
属性中的真实图片地址,同时将isLoaded
设置为true
,并断开观察器。onMounted
钩子函数在组件挂载时被调用。这里先使用nextTick
确保 DOM 更新完成后,获取所有带有data-src
属性的图片元素,并对每个元素调用loadImage
函数来开始监听它们的加载时机。onBeforeUnmount
钩子函数在组件卸载前被调用。它获取所有带有data-src
属性的图片元素对应的观察器,并断开它们,以避免内存泄漏。
-
Vue3-lazyload库封装
-
1.首先,需要安装vue3-lazyload
这个库来辅助实现图片懒加载功能。可以通过以下命令进行安装:
npm install vue3-lazyload
2.
import { ref, onMounted, onBeforeUnmount } from 'vue';
import lazyLoad from 'vue3-lazyload';
export default function useLazyLoad() {
// 创建一个响应式的对象来存储图片加载状态
const isLoaded = ref(false);
// 定义加载图片的函数
const loadImage = (imgElement) => {
if (!imgElement) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
lazyLoad(entry.target);
isLoaded.value = true;
observer.disconnect();
}
});
});
observer.observe(imgElement);
};
// 在组件挂载时,绑定加载图片的事件
onMounted(() => {
const imgElements = document.querySelectorAll('img[data-src]');
imgElements.forEach((img) => {
loadImage(img);
});
});
// 在组件卸载前,清除所有的观察器
onBeforeUnmount(() => {
const observers = [];
const imgElements = document.querySelectorAll('img[data-src]');
imgElements.forEach((img) => {
const observer = img.__observer;
if (observer) {
observers.push(observer);
}
});
observers.forEach((observer) => {
observer.disconnect();
});
});
return {
isLoaded
};
}
1.首先创建了一个isLoaded
的响应式引用,用于跟踪图片是否已经加载完成。
2.loadImage
函数用于创建一个IntersectionObserver
来观察图片是否进入到浏览器的可视区域。当图片进入可视区域时,就使用vue3-lazyload
库来加载图片,并将isLoaded
设置为true
,然后断开观察器。
3.在onMounted
钩子函数中,获取所有带有data-src
属性的图片元素,并对每个元素调用loadImage
函数来开始监听它们的加载时机。
4.在onBeforeUnmount
钩子函数中,获取所有带有data-src
属性的图片元素对应的观察器,并断开它们,以避免内存泄漏。
四、性能优化考虑
在实现图片懒加载过程中可以进行的一些性能优化措施。比如合理设置IntersectionObserver
的阈值,避免过于频繁地检查图片是否进入可视区;对图片进行适当的压缩处理,减少图片加载的数据量等。
通过性能监测工具(如 Chrome 开发者工具中的性能面板)来评估懒加载的效果以及进一步优化的方向。