過去,實現懶加載通常需要監聽 scroll
事件,并結合 getBoundingClientRect()
等方法計算元素位置,代碼不僅繁瑣,而且頻繁的計算會引發性能問題。
現代瀏覽器提供了 Intersection Observer API
,讓我們得以用一種極其高效和簡潔的方式來實現懶加載。多簡潔?核心邏輯只需 10 行代碼。
第一步:HTML 結構準備
懶加載的原理很簡單:我們不直接將圖片的 URL 放在 src
屬性里,而是先放在一個自定義的 data-*
屬性(如 data-src
)中。src
屬性可以指向一個極小的占位符圖片(比如一個 1x1 像素的透明 GIF 或低質量的模糊圖),以避免出現 broken image 圖標。
第二步:JavaScript 魔法(10 行代碼實現)
現在,讓我們見證奇跡。創建一個 lazy-load.js
文件,并寫入以下代碼:
就是這樣!沒有復雜的計算,沒有混亂的事件監聽器。代碼清晰、高效,并且符合現代 Web 標準。
代碼解析:為什么它能工作?
Intersection Observer
(交叉觀察器) 是一個瀏覽器 API,它允許我們異步地觀察目標元素與其祖先元素或頂級文檔視窗(viewport)的交叉狀態。通俗地說,它能高效地告訴我們:“這個元素現在進入/離開屏幕了!”
讓我們分解一下這 10 行代碼:
document.querySelectorAll('.lazy')
: 我們選中所有帶有 .lazy
類的圖片元素。new IntersectionObserver(callback)
: 我們創建了一個觀察器。它的構造函數接收一個回調函數,當目標元素的可見性發生變化時,這個回調函數就會被觸發。entries
: 這是回調函數接收的參數,是一個數組,包含了所有發生可見性變化的被觀察元素的信息。entry.isIntersecting
: 這是一個布爾值,true
代表目標元素至少有一部分進入了視口,false
則代表它完全離開了視口。這是我們實現懶加載的關鍵判斷。img.src = img.dataset.src
: 一旦圖片可見,我們就執行核心操作:將存儲在 data-src
中的真實圖片 URL 賦值給 src
屬性。瀏覽器會自動開始下載并顯示圖片。observer.unobserve(img)
: 這是至關重要的一步優化。一旦圖片被加載,我們就不再需要觀察它了。調用 unobserve
可以告訴觀察器停止對該元素的監視,從而節省了寶貴的計算資源。observer.observe(image)
: 最后,我們啟動觀察器,讓它開始監視每一個需要懶加載的圖片。
進階優化:預加載
Intersection Observer
還允許我們傳入一個配置對象,來更精細地控制“交叉”的定義。其中 rootMargin
屬性非常有用。
rootMargin
可以在視口(root)的每一邊添加一個“外邊距”,提前或延遲觸發回調。例如,我們可以讓圖片在距離進入視口還有 200px 時就開始加載。
這樣設置后,用戶向下滾動時,圖片會“提前”加載,當圖片真正進入視口時已經準備好了,體驗會更加流暢。
Intersection Observer
不僅代碼量極少,而且在性能上遠超傳統方法,因為它將復雜的計算交給了瀏覽器底層去高效處理,不會阻塞主線程。
閱讀原文:https://mp.weixin.qq.com/s/Wa5S_BNFfQn7bwfLW6hpjg
該文章在 2025/6/18 9:54:19 編輯過