自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

loading='lazy' 不要再用啦!這才是現(xiàn)代懶加載的正確打開方式

開發(fā) 前端
如果是非常簡單的頁面,那么使用 loading="lazy"? 確實是最快捷的方式;但如果你需要更多控制、更復(fù)雜的體驗,IntersectionObserver 才是更強大的選擇!?

Hello,大家好,我是 Sunday

懶加載(Lazy Loading)一直是前端性能優(yōu)化的常見方式。不知道從什么時候開始 <img loading="lazy"> 這樣的屬性方案開始大行其道,很多同學(xué)并不了解 <img loading="lazy"> 的作用,就直接把它放到項目里進行使用,不知不覺就為自己埋下了大坑!

loading="lazy" 的作用

圖片

根據(jù) MDN的介紹,我們可以很清楚的了解 <img loading="lazy"> 的作用, 很多同學(xué)在看到這個屬性后都會“虎軀一震”,覺得:“這簡直是完美解決懶加載的方案啊,不用寫 JS 了,真香!”

但現(xiàn)實遠(yuǎn)沒有那么理想:瀏覽器的懶加載行為遠(yuǎn)不如你想象中的那么“聰明”:

1. 加載觸發(fā)點不穩(wěn)定,不可控

瀏覽器內(nèi)部定義了一個“可見區(qū)域附近的預(yù)加載區(qū)域”(preload margin),當(dāng)圖片即將進入視口時才加載。

但這個區(qū)域是 不可控的!不同瀏覽器、不同版本、甚至不同網(wǎng)絡(luò)環(huán)境下的觸發(fā)條件都不一樣!

舉個例子:

  • 在 Chrome 中可能是距離視口下方 1250px 就開始加載。
  • 在 Safari 中可能必須接近視口 200px 才觸發(fā)。
  • 而在 Firefox 中,行為又完全不同。

所以你可能會發(fā)現(xiàn)用戶已經(jīng)快滾到圖片了,但圖片還沒開始加載,造成“白屏”或者“圖片加載卡頓” 的問題

2. 首屏關(guān)鍵圖被延遲加載

很多同學(xué)直接在所有 <img> 標(biāo)簽上加上 loading="lazy",包括首屏 Banner、Logo、首圖等關(guān)鍵視覺內(nèi)容。

這是個大坑!

首屏圖片本應(yīng)盡早加載,提升 FCP(首次內(nèi)容繪制)性能,但 loading="lazy" 會把它推遲,導(dǎo)致頁面看起來很慢。

比如,如下代碼就會導(dǎo)致 FCP 時間變長、LCP 分?jǐn)?shù)下降、用戶體驗變差

<!-- 下面的 Logo 是首屏元素,卻用了 lazy,導(dǎo)致 Logo 顯示很慢 -->
<img src="/logo.png" loading="lazy" alt="品牌Logo" />

3. 加載狀態(tài)不可監(jiān)聽

在實際開發(fā)中,我們通常需要 監(jiān)聽圖片懶加載的狀態(tài),比如:增加占位圖

各種色塊的占位圖各種色塊的占位圖

但是,loading="lazy" 不可監(jiān)聽!這就會導(dǎo)致以下功能完全無法實現(xiàn):

  • 沒法給圖片加載過程加動畫(比如漸現(xiàn))
  • 沒法給圖片加載失敗加容錯處理(比如加載失敗替換默認(rèn)圖)
  • 沒法實現(xiàn)漸進式加載體驗(如先顯示模糊圖再加載高清圖)

這些需求,loading="lazy" 全都做不到!

4. 只能用于 <img> 和 <iframe>,場景非常局限

如果你想懶加載:

  • 背景圖?
  • 視頻?
  • 組件?
  • 滾動區(qū)域的 DOM?
  • React / Vue 的動態(tài)子組件?

都不能用 loading="lazy",完全不適配,只能乖乖用 JS 自己監(jiān)聽。

正確的方案:IntersectionObserver

當(dāng)瀏覽器原生的 loading="lazy" 不能滿足我們在 加載控制、動畫處理、骨架屏、兼容性、多元素懶加載 等方面的需求時,更強大、更靈活、更現(xiàn)代的方式就是: IntersectionObserver。

圖片圖片

IntersectionObserver 是瀏覽器提供的一個 API,它允許你觀察某個 DOM 元素是否進入或離開視口(或某個指定容器),從而可以在適當(dāng)時機觸發(fā)事件,比如:

  • 加載圖片
  • 動態(tài)加載組件
  • 觸發(fā)動畫
  • 懶加載內(nèi)容模塊

它會持續(xù)監(jiān)聽一個目標(biāo)元素是否“交叉”進入指定容器(通常是視口),并觸發(fā)回調(diào):

const observer = new IntersectionObserver(callback, options)
observer.observe(targetElement)

以 Vue 為例,我們可以通過如下方式來直接完成 懶加載指令

// vue3 指令實現(xiàn)(使用 @vueuse/core 的 useIntersectionObserver)
app.directive('lazy', {
  mounted(el, binding) {
    const { stop } = useIntersectionObserver(
      el,
      ([{ isIntersecting }]) => {
        if (isIntersecting) {
          el.src = binding.value
          stop()
        }
      },
    )
  },
})
<img v-lazy="imageUrl" alt="圖片">

這種方式雖然比 loading="lazy" 要復(fù)雜,但是在實際企業(yè)開發(fā)中,這才是最可控的方式。

一句話總結(jié)下:如果是非常簡單的頁面,那么使用 loading="lazy" 確實是最快捷的方式;但如果你需要更多控制、更復(fù)雜的體驗,IntersectionObserver 才是更強大的選擇!

責(zé)任編輯:武曉燕 來源: 程序員Sunday
相關(guān)推薦

2021-11-25 07:43:56

CIOIT董事會

2021-11-10 16:03:42

Pyecharts Python可視化

2019-03-17 16:48:51

物聯(lián)網(wǎng)云計算數(shù)據(jù)信息

2022-08-16 08:33:06

DevOps實踐

2020-05-09 10:35:06

遞歸面試算法

2018-10-29 15:20:03

2021-10-09 15:49:00

5G網(wǎng)絡(luò)技術(shù)

2021-06-07 10:05:56

性能優(yōu)化Kafka

2025-01-15 12:31:46

2016-03-01 14:51:18

云計算DevOps

2022-03-22 07:37:04

FeignSpringRibbon

2016-01-08 11:00:14

OpenStack云計算

2019-02-20 14:35:57

區(qū)塊鏈數(shù)字貨幣比特幣

2023-07-10 09:38:06

兼容性測試方案

2017-08-02 10:43:39

深度學(xué)習(xí)TensorFlowRNN

2020-07-05 09:17:20

云桌面

2020-06-04 15:16:46

云計算

2022-06-22 09:06:54

CSS垂直居中代碼

2021-06-21 09:36:44

微信語音轉(zhuǎn)發(fā)

2021-01-11 10:47:09

IT部門網(wǎng)絡(luò)管理
點贊
收藏

51CTO技術(shù)棧公眾號