圖片懶加載的一些想法與實踐

圖片懶加載

簡單的來講:javascript

就是一些須要加載的圖片,咱們先使用佔位的方式(用於判斷是否存在視圖內。),減小網絡下載圖片對首屏渲染的壓力,從而使得首屏更快的loadhtml

(如下但願結合源碼服用)前端

step 1:

第一步確定是run一個簡單的demo能實現替換佔位符。而且進行判斷是否在view視圖內。vue

https://github.com/ZWkang/jav...java

這個demo能夠看得出,是實現了以前提到的幾點。git

它使用offset類的api進行獲取位置,並進行遍歷,再計算從而得到相對整個視圖的位置。簡單的替換圖片進行這種獲取轉換src的方法es6

能夠看出來上面這段代碼其實是很糟糕的。

  1. 它沒有任何的封裝
  2. 它沒有可讓我輸入的配置
  3. 它的獲取性能過低效。(咱們應該知道offset之類的api爲了得到大小,總會觸發一次Reflow,來進行位置的獲取。)
  4. 它支持項太少了。只支持了咱們特定的data-src

step 2:

前端迭代過程咱們能夠發現。不少時候新的api的出現,是一部分是爲了支持新的特性,一部分是爲了彌補不夠用github

前面說到很低效的offset類apiapi

並不夠用。因此出現了緩存

此處通過一段時間的思考

https://github.com/ZWkang/jav...

進行迭代到這一版、

事實上這一版的代碼寫的也是很是的糟糕的。由於個人es6在那個時候並非很好。

能夠在變量的聲明上看出。不少時候我是沒轉變過來的。可是那不影響

簡單的講一下

首先固然是聲明一些將被緩存的變量

而後能夠發現,這一版本引入了Setting可配置。

lazyload是一個對象,一些實例方法掛載在上面。這裏沒有用class之類的,也就是使用,下面會說一下這種寫法。頁面共享一個實例。

在這一版咱們引入了getBoundingClientRect

使用getBoundingClientRect來判斷。明顯是比較高效的。並且性能損耗並不會比offset類的高。

能夠說這一版解決了初版咱們發現的幾個問題。

引入了配置。UMD的模塊寫法。獲取的api判斷是否在視圖內優雅降級。支持了更多項,srcset backgroundImage(固然對於srcset的處理其實並無很好的方法。它仍是有一些坑的。)

固然咱們能夠看看這樣寫法的用處。

咱們能夠很簡單的侵入式的使用在vue上。

https://github.com/ZWkang/sim...

能夠看看這個。核心代碼基本是徹底一致的。

只是獲取元素須要在渲染後獲取。否則會致使獲取不了元素。固然這個涉及到了vue的執行時機。

Vue.use(lazy, {
  background: true,
  backgroundTag: 'data-background',
  imgSrc: true,
  imgTag: 'data-src',
  parent: null,
  srcset: false,
  srcsetTag: 'data-srcset',
  delayTime: 200,
  rendered: function () { },
  deleleData: true,
  firstLoad: true
})

在use 安裝的時候設置配置文件,注入在vue組件的實例實際上在這個時候就已經有了對應的配置

updated: function () {
    this.lazyload.init({})
  },
  destroyed: function () {
    this.lazyload.cache = []
  }

而後只須要簡單的配置就可使用咱們的lazyload組件了。

實際上這種方法。是徹底的將vue當成普通的html dom來處理了。

不少vue的高級東西並無用到。可是這樣確實是很簡單不是麼。

而這樣子的作法很便捷,可是也有缺陷。那就是,多個子組件的時候。

你的組件init初始須要放在相對的父級組件使用,而不是多個子組件使用。。

更好的方式是應該使用一個component的組件來承載整個lazyload的流程


step 3:

其實上面步驟的lazyload組件已是可用了。

那麼第三版咱們還能夠對它進行什麼改造。

https://github.com/ZWkang/jav...

在第三版咱們引入一個更新的api

IntersectionObserver

這個observer也是更爲強勁。它能夠直接進行判斷是否在視圖內,有一個boolean的處理值。而且還攜帶一些屬性。

使用也很簡單。

只須要new初始化時候傳入對應的回調函數。而後observe element節點便可

第三版咱們還能夠進行更好的優化

例如加入loading圖片 error圖片 之類的配置文件

而且將咱們的邏輯代碼更抽象,例如一些判斷的if else 能夠用iife直接判斷返回一個函數

減小一些if else的判斷。而是在第一次解析的時候就肯定了。

這裏。咱們能夠看一下代碼職責分離 耦合度低的好處

我在第二版寫的srcChange 是獨立的函數,傳入對應的節點處理對應的事情。

而在第三版即便咱們添加新的處理api

這個srcChange也是徹底複用的。是徹底。

圖片增長loading error的處理。

就是new Image代理咱們獲取圖片。onload成功以後就再替換。預加載的原理跟這個差很少,預加載就是將全部圖片獲取再進行Image獲取


唔。大概這個時候這個lazyload插件就到達可用的程度了(固然可不可用我也不知道,由於我沒有在實際狀況下生產狀況使用(歡迎使用後的反饋),從簡單測試來看,它是可行的)

我很喜歡寫小demo,由於它不大。我能夠任意重構,想怎麼搞就怎麼搞。

唔。很歡迎很歡迎交流啊!!!!!!

可是不要噴我。我讀書少,你噴不贏個人。

最後是祝福語。

但願閱讀這篇文章能有一點點幫助到你。

也厚臉皮求一下下star。固然該倉庫還有一些寶藏~~


相關文章
相關標籤/搜索