日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

圖像延遲加載

想要得到更好的性能體驗(yàn),只靠資源壓縮與恰當(dāng)?shù)奈募袷竭x型,是很難滿足期望的。我們還需要針對(duì)資源加載過程進(jìn)行優(yōu)化。

什么是延遲加載?

下圖是京東商城的手機(jī)端首頁,當(dāng)元素沒有滑動(dòng)到視線內(nèi)時(shí),圖片src屬性放置了一個(gè)很小的圖片,init_src屬性放置了真正的圖片,只要當(dāng)該元素滑動(dòng)到視線內(nèi)部,才會(huì)將init_src屬性賦值給src去加載真實(shí)的圖片,這就是一個(gè)簡(jiǎn)單的圖片延遲加載的過程。

web前端性能優(yōu)化——圖片加載的優(yōu)化

 


web前端性能優(yōu)化——圖片加載的優(yōu)化

 

傳統(tǒng)方式延遲加載

就是事件監(jiān)聽的方式,通過監(jiān)聽scroll事件與resize事件,并在事件的回調(diào)函數(shù)中去判斷,需要進(jìn)行延遲加載的圖片是否進(jìn)入視窗區(qū)域。

我們只需要關(guān)注三個(gè)屬性。

  • class屬性,稍后會(huì)在JAVAScript中使用類選擇器選取需要延遲加載處理的〈img〉標(biāo)簽。
  • src屬性,加載前的占位符圖片,可用Base64圖片或低分辨率的圖片。
  • data-src屬性,通過該自定義屬性保存圖片真實(shí)的URL外鏈。
web前端性能優(yōu)化——圖片加載的優(yōu)化

 

加入頁面中有多張這樣的圖片需要加載。具體的JavaScript實(shí)現(xiàn)邏輯如下,在文檔的DOMContentLoaded事件中,添加延遲加載處理邏輯,首先獲取class屬性名為lazy的所有〈img〉標(biāo)簽,將這些標(biāo)簽暫存在一個(gè)名為lazyImages的數(shù)組中,表示需要進(jìn)行延遲加載但還未加載的圖片集合。當(dāng)一個(gè)圖片被加載后,便將其從lazyImages數(shù)組中移除,直到lazyImages數(shù)組為空時(shí),表示所有待延遲加載的圖片均已經(jīng)加載完成,此時(shí)便可將頁面滾動(dòng)事件移除。

這里使用了getBoundingClientRect()函數(shù)獲取元素的相對(duì)位置.

        rectObject = object.getBoundingClientRect();

rectObject.top:元素上邊到視窗上邊的距離;

rectObject.right:元素右邊到視窗左邊的距離;

rectObject.bottom:元素下邊到視窗上邊的距離;

rectObject.left:元素左邊到視窗左邊的距離;

web前端性能優(yōu)化——圖片加載的優(yōu)化

 

對(duì)于只可上下滾動(dòng)的頁面,判斷一個(gè)圖片元素是否出現(xiàn)在屏幕視窗中的方法其實(shí)顯而易見,即當(dāng)元素上邊緣距屏幕視窗頂部的top值小于整個(gè)視窗的高度window.innerHeight時(shí),預(yù)加載的事件處理代碼如下:

document.addEventListener(DOMContentLoaded, function() {
      const imags = [].slice.call(document.querySelector('.lazy'))
      const active = false; // 限制函數(shù)被頻繁調(diào)動(dòng)
      function load() {
        if(active === false) {
          active = true
          setTimeout(() => {
            imags.forEach((img) => {
              const objPos = img.getBoundingClientRect();
              if(objPos.top <= window.innerHeight && objPos.bottom >=0 && img.display !== 'done') {
                img.src = img.dataset.src;
                img.classList.remove('lazy')
                imags.filter((i) => (i !== img))
                if(imags.length === 0) {
                  document.removeEventListener('scroll', load)
                  window.removeEventListener('resize', load)
                  window.removeEventListener('orientationchange', load)
                }
  
              }
            })
            active = false
          }, 200)
        }

      }

      document.addEventListener('scroll', load)
      window.addEventListener('resize', load)
      window.addEventListener('orientationchange', load)

    })

這種方式的有點(diǎn)就是兼容性比較好,缺點(diǎn)是頻繁地進(jìn)行計(jì)算必然會(huì)影響性能,代碼也會(huì)比較繁瑣。

實(shí)現(xiàn)圖片的延遲加載:Intersection Observer方式

現(xiàn)代瀏覽器已大多支持了Intersection Observer API,用一句話簡(jiǎn)述:每當(dāng)因頁面滾動(dòng)或窗口尺寸發(fā)生變化,使得目標(biāo)元素(target)與設(shè)備視窗或其他指定元素產(chǎn)生交集時(shí),便會(huì)觸發(fā)通過Intersection Observer API配置的回調(diào)函數(shù),在該回調(diào)函數(shù)中進(jìn)行延遲加載的邏輯處理,會(huì)比傳統(tǒng)方式顯得更加簡(jiǎn)潔而高效。

簡(jiǎn)單來說,目標(biāo)元素的可見性變化時(shí),就會(huì)調(diào)用觀察器的回調(diào)函數(shù) callback。

callback一般會(huì)觸發(fā)兩次。一次是目標(biāo)元素剛剛進(jìn)入視口(開始可見),另一次是完全離開視口(開始不可見)。

 document.addEventListener(DOMContentLoaded, function() {
        const imags = [].slice.call(document.querySelector('.lazy'))
        if(window.IntersectionObserver && window.IntersectionObserverEntry && window.IntersectionObserverEntry.prototype.intersectionRatio) {
          var lazyImgObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry)=> {
              if(entry.isIntersecting) {
                var lazyImg = entry.target;
                lazyImg.src = lazyImg.dataset.src;
                lazyImg.classList.remove('lazy');
                lazyImgObserver.unobserve(lazyImg)
              }
            })
          })
          imags.forEach((img) => {
            lazyImgObserver.observe(img)
          })
        }
   
      })

這種方式判斷元素是否出現(xiàn)在視窗中更為簡(jiǎn)單直觀,應(yīng)在實(shí)際開發(fā)中盡量使用,但其問題是并非所有瀏覽器都能兼容。

(1)做好盡量完備瀏覽器兼容性檢查,對(duì)于兼容Intersection Observer API的瀏覽器,采用這種方式進(jìn)行處理,而對(duì)于不兼容的瀏覽器,則切換回傳統(tǒng)的實(shí)現(xiàn)方式進(jìn)行處理。 (2)使用相應(yīng)兼容的polyfill插件,在W3C官方GitHub賬號(hào)下就有提供。

實(shí)現(xiàn)圖片的延遲加載:css類名方式

這種實(shí)現(xiàn)方式通過CSS的background-image屬性來加載圖片,與判斷〈img〉標(biāo)簽src屬性是否有要請(qǐng)求圖片的URL不同,CSS中圖片加載的行為建立在瀏覽器對(duì)文檔分析基礎(chǔ)之上。

  document.addEventListener(DOMContentLoaded, function() {
        const imags = [].slice.call(document.querySelector('.lazy'))
        if(window.IntersectionObserver && window.IntersectionObserverEntry && window.IntersectionObserverEntry.prototype.intersectionRatio) {
          var lazyImgObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry)=> {
              if(entry.isIntersecting) {
                var lazyImg = entry.target;
                lazyImg.classList.add('visible');
                lazyImgObserver.unobserve(lazyImg)
              }
            })
          })
          imags.forEach((img) => {
            lazyImgObserver.observe(img)
          })
        }
   
      })
web前端性能優(yōu)化——圖片加載的優(yōu)化

 

這種方式限制于需要提前寫好css樣式。

原生的延遲加載支持

除了上述通過開發(fā)者手動(dòng)實(shí)現(xiàn)延遲加載邏輯的方式,從Chrome 75版本開始,已經(jīng)可以通過〈img〉和〈iframe〉標(biāo)簽的loading屬性原生支持延遲加載了,loading屬性包含以下三種取值。

● lazy:進(jìn)行延遲加載。 ● eager:立即加載。 ● auto:瀏覽器自行決定是否進(jìn)行延遲加載。

測(cè)試:image標(biāo)簽就是 img

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- <script src="js/file2.js"></script> -->
  <!-- <script src="js/file3.js"></script> -->
  <!-- <link rel="stylesheet" href="css/index.css"> -->
  <style>
    img {
      width: 700px;
      height: 200px;
      display: block;
    }
  </style>
</head>
<body>

  
  
  <imgage loading="lazy" src='./image/home-1.png' alt="photo" />
  <imgage loading="lazy" src='./image/home-2.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-3.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-4.png' alt="photo" />
  <imgage loading="lazy" src='./image/home-5.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-6.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-7.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-8.png' alt="photo" />
  
  <imgage loading="lazy" src='./image/home-9.png' alt="photo" />
  <imgage loading="lazy" src='./image/home-10.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-11.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-12.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-13.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-14.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-15.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-16.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-17.png' alt="photo" />
  <imgage loading="lazy" src='./image/home-18.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-19.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-20.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-21.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-22.png' alt="photo" />
  
  <imgage loading="lazy" src='./image/home-23.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-24.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-25.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-26.png' alt="photo" />
  <imgage loading="lazy" src='./image/home-27.png' alt="photo" />

  <imgage loading="lazy" src='./image/home-28.png' alt="photo" />


  <imgage loading="lazy" src='./image/home-29.png' alt="photo" />

<imgage loading="lazy" src='./image/home-30.png' alt="photo" />



</body>
</html>
web前端性能優(yōu)化——圖片加載的優(yōu)化

 

可以看到,首次加載的個(gè)數(shù)是13個(gè),首屏一般只能放下4個(gè)左右,13個(gè)以后的img滾動(dòng)到視線內(nèi)部會(huì)自動(dòng)去加載。

實(shí)踐發(fā)現(xiàn)有以下幾個(gè)特點(diǎn):

  1. Lazy loading加載數(shù)量與屏幕高度有關(guān),高度越小加載數(shù)量越少,但并不是線性關(guān)系。
  2. Lazy loading加載數(shù)量與網(wǎng)速有關(guān),網(wǎng)速越慢,加載數(shù)量越多,但并不是線性關(guān)系。
  3. Lazy loading加載沒有緩沖,滾動(dòng)即會(huì)觸發(fā)新的圖片資源加載。
  4. Lazy loading加載在窗口resize尺寸變化時(shí)候也會(huì)觸發(fā),例如屏幕高度從小變大的時(shí)候。
  5. Lazy loading加載也有可能會(huì)先加載后面的圖片資源,例如頁面加載時(shí)滾動(dòng)高度很高的時(shí)候。

與JavaScript有關(guān)的幾個(gè)行為特征:

  1. 判斷瀏覽器是否支持原生loading,最好使用'loading' in XXX判斷。
  2. 獲取loading屬性值可以直接img.loading;
  3. 原生loading不可寫,不可訪問例如HTMLImageElement.prototype.loading會(huì)報(bào)錯(cuò)Illegal invocation。
  4. 如果要使用,注意做兼容性處理。

分享到:
標(biāo)簽:優(yōu)化
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定