<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖片懶加載幾個(gè)版本的實(shí)現(xiàn)對比

          共 1703字,需瀏覽 4分鐘

           ·

          2021-11-09 22:12

          大廠技術(shù)??高級前端??Node進(jìn)階

          點(diǎn)擊上方?程序員成長指北,關(guān)注公眾號

          回復(fù)1,加入高級Node交流群

          背景

          圖片懶加載是針對圖片加載時(shí)機(jī)的一種優(yōu)化,在一些圖片量比較大的網(wǎng)站(比如電商網(wǎng)站首頁,或者團(tuán)購網(wǎng)站、小游戲首頁等),如果我們嘗試在用戶打開頁面的時(shí)候,就把所有的圖片資源加載完畢,那么很可能會造成白屏、卡頓等現(xiàn)象,因?yàn)閳D片真的太多了,一口氣處理這么多任務(wù),瀏覽器做不到啊!

          懶加載是為了讓瀏覽器只加載可視區(qū)內(nèi)的圖片,可視區(qū)外的大量圖片不進(jìn)行加載,當(dāng)頁面滾動(dòng)到后面去的時(shí)候再進(jìn)行加載。這樣做有很多好處可以增加首屏加載的速度,畢竟,用戶點(diǎn)開頁面的瞬間,呈現(xiàn)給他的只是首屏,我們只要把首屏的資源圖片加載處理就可以了,至于下面的圖片,當(dāng)用戶下滑當(dāng)當(dāng)前位置的時(shí)候,在加載出來也是沒問題的,對于性能壓力也小了,用戶體驗(yàn)也沒有變差。

          解答

          圖片懶加載的原理就是需要知道圖片是否在可視區(qū)內(nèi)了,當(dāng)圖片到達(dá)可視區(qū)內(nèi)就需要去請求對應(yīng)的圖片加載出來

          頁面中的img標(biāo)簽一般如下寫

          class="lazyload"?src="placeholder.jpg"?src="real_image.jpg"?/>

          其中src首先賦值一個(gè)占位的圖片,一般是一個(gè)很小的圖片,進(jìn)行占位,src是實(shí)際需要展示的圖片,原理就是當(dāng)圖片在可視區(qū)內(nèi)的時(shí)候?qū)rc的圖片選渲染出來即可。

          1、原生實(shí)現(xiàn)

          Chrome 76 將原生支持圖片的惰性加載,支持對img和iframe進(jìn)行延遲加載,只需要將loading屬性設(shè)置為lazy即可。

          <img?src="celebration.jpg"?loading="lazy"?alt="..."?/>
          <iframe?src="video-player.html"?loading="lazy">iframe>

          原生實(shí)現(xiàn)的好處是,不需要任何腳本,純原生HTML即可,簡單方便,支持多種屬性

          • lazy:對資源進(jìn)行延遲加載。
          • eager:立即加載資源。
          • auto:瀏覽器自行判斷決定是否延遲加載資源。

          原生的壞處就是在于瀏覽器的支持率不是很高,將來肯定是非常好的。

          我們知道由于瀏覽器的支持率不是很好,上面的方案固然很好,但是使用的并不是很多,所以下面介紹幾種更加常見的懶加載方案。

          2、Element.getBoundingClientRect()

          getBoundingClientRect返回值是一個(gè) DOMRect 對象,這個(gè)對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關(guān)的CSS 邊框集合 。DOMRect 對象包含了一組用于描述邊框的只讀屬性——left、top、right和bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。

          有了這個(gè)API后我們很同意獲取圖片的top值,當(dāng)top值小于可視區(qū)的高度的時(shí)候就可以任何圖片進(jìn)入了可視區(qū),直接加載圖片即可

          element.getBoundingClientRect().top?document.documentElement.clientHeight

          由于需要在滾動(dòng)的時(shí)候去監(jiān)聽圖片的位置,所以我們需要使用到window.onscroll事件,我們在事件內(nèi)部處理相關(guān)的邏輯即可。

          3、通過相對計(jì)算獲取元素位置

          1. 通過document.documentElement.clientHeight獲取屏幕可視窗口高度。
          2. 通過element.offsetTop獲取元素相對于文檔頂部的距離。
          3. 通過document.documentElement.scrollTop獲取瀏覽器窗口頂部與文檔頂部之間的距離,也就是滾動(dòng)條滾動(dòng)的距離。然后判斷2-3<1是否成立,如果成立,元素就在可視區(qū)域內(nèi)。
          element.offsetTop?-??document.documentElement.scrollTop?document.documentElement.clientHeight

          此方法也需要在滾動(dòng)的時(shí)候去監(jiān)聽圖片的位置,所以我們需要使用到window.onscroll事件,我們在事件內(nèi)部處理相關(guān)的邏輯即可。

          4、使用IntersectionObserver

          const?observer?=?new?IntersectionObserver(callback,?observerConfig)
          const?imgList?=?document.querySelectorAll(".lazyload");
          const?observer?=?new?IntersectionObserver(entries?=>?{
          ????entries.forEach(item?=>?{
          ????????if?(item.isIntersecting)?{
          ????????????item.target.src?=?item.target.dataset.origin;?//?判斷在可視區(qū)了,把data-origin的值放到src
          ????????????observer.unobserve(item.target);?//?已經(jīng)加載過的圖片停止進(jìn)行監(jiān)聽
          ????????}
          ????});
          });
          imgList.forEach(item?=>?observer.observe(item));

          補(bǔ)充

          1、優(yōu)化

          由于上面某些情況是需要使用到window.scroll事件的,所以我們可以增加節(jié)流來減少事件處理函數(shù)的調(diào)用次數(shù)。假設(shè)我們判斷是否可視區(qū)邏輯為函數(shù)loadImage那么我們可以如下處理。

          window.onscroll?=?throttle(loadImage,?500)

          2、拓展

          上面后續(xù)三種方法不僅僅可以使用在圖片的懶加載上面,其實(shí)所有可以懶加載的地方都可以通過這種方式進(jìn)行判斷,比如列表分頁加載,我們可以通過這種方式進(jìn)行判斷是否需要進(jìn)行下一頁的加載,比如我們需要埋曝光埋點(diǎn)的時(shí)候,可以通過這種方法判斷元素是否曝光,進(jìn)行埋點(diǎn)事件的觸發(fā)。

          Node 社群


          我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。


          ???“分享、點(diǎn)贊在看” 支持一波??

          瀏覽 46
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  北条麻妃精品99青青久久 | 久久久理论 | 久久夜色精品国产噜噜v6 | 天堂va欧美ⅴa亚洲va一夜 | 国产一级淫乱视频 |