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

