圖片懶加載

前言

圖片的懶加載一直都是大廠熱門的考題,可爲何他能成爲大廠們紛紛趨之若鶩的香饃饃呢,這就要提到它的好處了——性能優化,對就是性能優化,要知道,全部的產品最終是要服務於客戶的,而誰能使客戶的體驗感更好,誰就能笑到最後,而性能就是其中最重要的一環。web

什麼是圖片懶加載?

懶加載突出一個「懶」字,懶就是拖延遲的意思,因此「懶加載」說白了就是延遲加載,好比咱們加載一個頁面,這個頁面很長很長,長到咱們的瀏覽器可視區域裝不下,那麼懶加載就是優先加載可視區域的內容,其餘部分等進入了可視區域在加載。數組

爲何要圖片懶加載?

懶加載是一種網頁性能優化的方式,它能極大的提高用戶體驗。就好比說圖片,圖片一直是影響網頁性能的主要元兇,如今一張圖片超過幾兆已是很常常的事了。若是每次進入頁面就請求全部的圖片資源,那麼可能等圖片加載出來用戶也早就走了。因此,咱們須要懶加載,進入頁面的時候,只請求可視區域的圖片資源。瀏覽器

原理

圖片懶加載,那咱們要實現懶加載,固然是要對圖片下手啦!性能優化

你們都知道,一張圖片就是一個標籤,而圖片的來源主要是src屬性。瀏覽器是否發起親求就是根據是否有src屬性決定的。markdown

既然這樣,那麼咱們就要對標籤的src屬性下手了,在沒進入可視區域的時候,咱們先不給這個標籤賦src屬性,這樣豈不是瀏覽器就不會發送請求了。app

實現

1.先介紹幾個和懶加載相關的API函數

  • 瀏覽器窗口的視口(viewport)高度(以像素爲單位);若是有水平滾動條,也包括滾動條高度。

var intViewportHeight = window.innerHeight;佈局

  • Element.clientHeight沒有CSS或內聯佈局框的元素的只讀屬性爲零;不然,它是元素的內部高度(以像素爲單位)。它包括填充,但不包括邊框,邊距和水平滾動條(若是存在)。

document.documentElement.clientHeight//獲取屏幕可視區域的高度性能

好啦好啦,講道理千遍萬遍,不如過一遍代碼,咱們上代碼!學習

與普通的圖片懶加載不一樣,以下這個多作了 2 個精心處理:

  • 圖片所有加載完成後移除事件監聽;
  • 加載完的圖片,從 imgList 移除;
let imgList = [...document.querySelectorAll('img')]
let length = imgList.length
// 把圖片查詢分配到一個數組
const imgLazyLoad = function() {
    let count = 0
   return (function() {
        let deleteIndexList = []
        imgList.forEach((img, index) => {
            let rect = img.getBoundingClientRect()
            if (rect.top < window.innerHeight) {
                img.src = img.dataset.src
                deleteIndexList.push(index)
                count++
                if (count === length) {
                    document.removeEventListener('scroll', imgLazyLoad)
                }
            }
        })
        imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
   })()
}

// 這裏最好加上防抖處理
document.addEventListener('scroll', imgLazyLoad)

複製代碼

其實吧,這個代碼對於大家這些大佬來講,挺簡單的,可是對於我這種小菜雞來講,仍是有點困難的,因此我仍是簡單講一下幾個點唄,夯實一下我本身的學習,因此大佬們多多擔待,多謝多謝!

  1. return (function() {}) 這其實就是一個自執行函數的實現。

而什麼是自執行函數呢?

自行調用的函數: 就是指,函數在頁面載入後或者以前就自行調用,無需藉助其餘函數或方法來啓動;

  1. img.getBoundingClientRect() 咳咳,我想大家都把這個這麼長的東東都在腦海裏讀了一遍吧!嘿嘿,我就沒有。

那言歸正傳,這個東西究竟是啥呢?咱們看到前面加了一個img.那我咱們確定知道它和圖片有關,那麼咱們來解釋一下唄:

img.getBoundingClientRect()就是圖片到視窗viewport的上或者左邊的距離,它有四個屬性

  • top 圖片上邊距離視窗上邊的距離
  • bottom 圖片下邊距離視窗上邊的距離
  • left 圖片左邊距離視窗左邊的距離
  • right 圖片右邊距離視窗左邊的距離

這樣說,是否是有點模糊呢? 因此說,我是個好人,精心爲大家「偷」了張圖片過來,看了下面那張圖,你就全懂了。

element-box-diagram.png

  1. document.removeEventListener('scroll', imgLazyLoad) 這裏呢,就是圖片所有加載完成後移除事件監聽,那它這樣乾的理由是什麼呢?

沒錯,就是防抖處理

簡而言之就是,經過移除監聽事件來實現防抖處理。

而,關於防抖,我就簡單說一下,不作過多解釋,個人下篇文章會講。什麼?你問下篇文章在哪?額。。。,我只能告訴你,等幾天!

防抖:防止抖動,以避免把一次事件誤執行屢次,影響性能,好比敲鍵盤就是一個天天都會接觸到的防抖操做。 4. !deleteIndexList.includes(index)

  • includes() 方法用於判斷字符串是否包含指定的子字符串。

    若是找到匹配的字符串則返回 true,不然返回 false。

注意: includes() 方法區分大小寫。

  • 我想不少同窗都對這個!deleteIndexListincludes(index)有點莫名其妙吧,那咱們來解析一下唄!
  1. 首先,deleteIndexList.includes(index)是一個方法,沒錯吧!它就是查詢deleteIndexList數組裏是否含有指定的index若是有,咱們就返回ture不然就返回false.
  2. 那前面再加上!是啥意思呢,咱們都知道!有取反的意思,因此在方法前面加上!就是對於方法的返回值取反。

總結: 因此這句代碼的做用就是刪除imgLIst裏面加載完的圖片。

總結

好了好了,介紹也介紹的差很少了,剩下的相信以小夥伴們的實例,解決它就是灑灑水的事情,因此咱們到這裏就結束咯,小夥伴們加油加油!拜拜

相關文章
相關標籤/搜索