vue3封裝Hooks實(shí)現(xiàn)圖片懶加載指南
一、引言
在現(xiàn)代 Web 開發(fā)領(lǐng)域,圖片懶加載的重要性不容小覷。
首先,它對頁面加載速度有著極大提升作用。當(dāng)頁面包含大量圖片時,若不采用懶加載,所有圖片會在頁面初始化時一同請求加載,這會導(dǎo)致加載時間過長。而懶加載僅在圖片進(jìn)入瀏覽器可視區(qū)域時才觸發(fā)加載,大大減少了初始加載的數(shù)據(jù)量,使關(guān)鍵資源(如 HTML、CSS 等)能優(yōu)先高效加載,讓用戶更快看到頁面布局并進(jìn)行交互。
其次,能有效節(jié)省用戶流量。對于移動用戶或流量有限的情況,懶加載按需加載圖片,避免了加載那些用戶可能根本不會看到的圖片,防止不必要的流量消耗。
二、圖片懶加載原理概述
簡單解釋什么是圖片懶加載。即圖片在進(jìn)入瀏覽器的可視區(qū)域時才進(jìn)行加載,而不是在頁面初始化時就全部加載所有圖片。
可以用一些簡單的示意圖或者類比的方式(比如把頁面想象成一個畫展,只有當(dāng)觀眾走到畫作前才會仔細(xì)去看這幅畫,也就是才加載這幅畫的細(xì)節(jié),類似圖片進(jìn)入可視區(qū)才加載)來幫助讀者更好地理解懶加載的概念。
三、封裝圖片懶加載 Hooks 的步驟
在這里我們提供啦兩個方式一種是原生封裝Hooks函數(shù),另一種是使用vue3-lazyload庫來實(shí)現(xiàn)圖片懶加
首先我們需要在src下創(chuàng)建一個hooks文件夾,在文件夾下新建一個useLazyLoad.js
原生Hooks封裝
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
export default function useLazyLoad() {
// 用于存儲圖片是否加載完成的響應(yīng)式狀態(tài)
const isLoaded = ref(false);
// 加載圖片的函數(shù)
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);
};
// 在組件掛載時執(zhí)行的邏輯
onMounted(() => {
// 使用nextTick確保DOM更新完成后再獲取圖片元素
nextTick(() => {
const imgElements = document.querySelectorAll('img[data-src]');
imgElements.forEach((img) => {
loadImage(img);
});
});
});
// 在組件卸載前執(zhí)行的邏輯
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是一個響應(yīng)式引用,用于跟蹤圖片是否已經(jīng)加載完成。loadImage函數(shù)創(chuàng)建了一個IntersectionObserver實(shí)例來觀察圖片是否進(jìn)入瀏覽器的可視區(qū)域。當(dāng)圖片進(jìn)入可視區(qū)域時,將圖片的src屬性設(shè)置為預(yù)先存儲在data-src屬性中的真實(shí)圖片地址,同時將isLoaded設(shè)置為true,并斷開觀察器。onMounted鉤子函數(shù)在組件掛載時被調(diào)用。這里先使用nextTick確保 DOM 更新完成后,獲取所有帶有data-src屬性的圖片元素,并對每個元素調(diào)用loadImage函數(shù)來開始監(jiān)聽它們的加載時機(jī)。onBeforeUnmount鉤子函數(shù)在組件卸載前被調(diào)用。它獲取所有帶有data-src屬性的圖片元素對應(yīng)的觀察器,并斷開它們,以避免內(nèi)存泄漏。
Vue3-lazyload庫封裝
1.首先,需要安裝vue3-lazyload這個庫來輔助實(shí)現(xiàn)圖片懶加載功能。
可以通過以下命令進(jìn)行安裝:
npm install vue3-lazyload
2.
import { ref, onMounted, onBeforeUnmount } from 'vue';
import lazyLoad from 'vue3-lazyload';
export default function useLazyLoad() {
// 創(chuàng)建一個響應(yīng)式的對象來存儲圖片加載狀態(tài)
const isLoaded = ref(false);
// 定義加載圖片的函數(shù)
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.首先創(chuàng)建了一個isLoaded的響應(yīng)式引用,用于跟蹤圖片是否已經(jīng)加載完成。
2.loadImage函數(shù)用于創(chuàng)建一個IntersectionObserver來觀察圖片是否進(jìn)入到瀏覽器的可視區(qū)域。當(dāng)圖片進(jìn)入可視區(qū)域時,就使用vue3-lazyload庫來加載圖片,并將isLoaded設(shè)置為true,然后斷開觀察器。
3.在onMounted鉤子函數(shù)中,獲取所有帶有data-src屬性的圖片元素,并對每個元素調(diào)用loadImage函數(shù)來開始監(jiān)聽它們的加載時機(jī)。
4.在onBeforeUnmount鉤子函數(shù)中,獲取所有帶有data-src屬性的圖片元素對應(yīng)的觀察器,并斷開它們,以避免內(nèi)存泄漏。
四、性能優(yōu)化考慮
在實(shí)現(xiàn)圖片懶加載過程中可以進(jìn)行的一些性能優(yōu)化措施。比如合理設(shè)置IntersectionObserver的閾值,避免過于頻繁地檢查圖片是否進(jìn)入可視區(qū);對圖片進(jìn)行適當(dāng)?shù)膲嚎s處理,減少圖片加載的數(shù)據(jù)量等。
通過性能監(jiān)測工具(如 Chrome 開發(fā)者工具中的性能面板)來評估懶加載的效果以及進(jìn)一步優(yōu)化的方向。
五、總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue中的watch是什么以及watch和computed的區(qū)別
這篇文章主要介紹了Vue中的watch是什么以及watch和computed的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
詳解使用vue-cli腳手架初始化Vue項(xiàng)目下的項(xiàng)目結(jié)構(gòu)
這篇文章主要介紹了詳解使用vue-cli腳手架初始化Vue項(xiàng)目下的項(xiàng)目結(jié)構(gòu),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
使用vue ant design分頁以及表格分頁改為中文問題
這篇文章主要介紹了使用vue ant design分頁以及表格分頁改為中文問題,具有很好的參考價值,希望對大家有所幫助。2023-04-04
uni-app制作小程序?qū)崿F(xiàn)左右菜單聯(lián)動效果
這篇文章主要介紹了uni-app制作小程序?qū)崿F(xiàn)左右菜單聯(lián)動效果,實(shí)現(xiàn)步驟和思路都很簡單,今天通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-11-11
vue3限制table表格選項(xiàng)個數(shù)的解決方法
這篇文章主要為大家詳細(xì)介紹了vue3限制table表格選項(xiàng)個數(shù)的解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04

