無限滾動的優(yōu)化方案(二):懶加載實現(xiàn)

之前對預(yù)加載的實現(xiàn)方案做了介紹,這一篇文章主要是我對圖片的懶加載的實現(xiàn)的一個總結(jié)鸦做。主要包括:

  1. 視區(qū)檢測
  2. 圖片懶加載及延遲顯示

實例簡介

之前一直對單頁應(yīng)用有興趣,所以自己寫了一個前端路由,相關(guān)的文章見這里夭禽,這個單頁應(yīng)用采取hash的方式實現(xiàn)路由。最終的實例頁面見這里谊路。倉庫在這里是一個經(jīng)典的單頁應(yīng)用讹躯。要做優(yōu)化的就是主頁的信息滾動。這些信息通過ajax從服務(wù)器端獲取凶异,這里為了方便蜀撑,服務(wù)器端會一直返回數(shù)據(jù),哪怕是重復(fù)的剩彬。頁面如下:

Paste_Image.png

懶加載

可以看到酷麦,頁面中,每一條消息都有一個圖片喉恋,這個時候沃饶,如果在dom剛剛建立好,就對所有的圖片進(jìn)行加載轻黑,此時糊肤,占用過多的下載通道(我的是每次顯示10條消息,接近頁面底部時會預(yù)加載)氓鄙,會導(dǎo)致后面的信息加載速度變慢馆揉,用戶體驗不好。而圖片懶加載是指:圖片進(jìn)入用戶視野才會進(jìn)行加載抖拦,而不是在dom樹一構(gòu)建好就進(jìn)行加載升酣。 道理很簡單,但是我在實現(xiàn)的過程中還是碰到了一些問題态罪,下面就是我的實現(xiàn)方案噩茄。

懶加載實現(xiàn)方案

總體變量以及函數(shù)定義

//記錄圖片的序號
let num = 0;
//記錄是否正在獲取數(shù)據(jù),保證請求只做一次
let state = true;
//記錄圖片數(shù)據(jù)复颈,index,src,height三個關(guān)鍵元素
var img_data =[];
//記錄表單的距離頁面頂端的距離
var list_height = 0;

function getH(obj) {
   //獲得對象距離頁面頂端的距離
}
function lazy_load(){
  //圖片懶加載的實現(xiàn)函數(shù)
}
function getInfo(){
   //從服務(wù)器端獲取商家發(fā)布的新信息
   //并向圖片數(shù)據(jù)中存放圖片信息 
}
function main(){
  //主函數(shù)
  //實現(xiàn)初始化
  //滾動事件的綁定等
}

獲取元素相對頁面頂部的高度

這個函數(shù)其實不難绩聘,主要涉及到目標(biāo)元素下面幾個屬性:

  1. node.offsetTop:相對其父元素的位置
  2. node.offsetParent: 元素的父元素
    所以,要獲取元素相對頁面頂部的高度耗啦,其實只需要進(jìn)行遞歸或者迭代就能實現(xiàn)凿菩,這里采用迭代實現(xiàn):
function getH(obj) {
    var h = 0;
    while (obj) {
        h += obj.offsetTop;
        obj = obj.offsetParent;
    }
    return h;
}

數(shù)據(jù)的緩存

程序中,通過Ajax從服務(wù)器獲取數(shù)據(jù)帜讲,每次最多獲取10條衅谷,在dom中,img標(biāo)簽最開始并不指定src舒帮,src存儲在ajax獲取到的信息中会喝,我將其存入:img_data中陡叠,與它一同存入的,還有該圖片的高度height肢执,第幾條信息index枉阵。
這里的height,可以采用上面的迭代得到预茄,但是每次迭代對資源損耗比較大兴溜,事實上也是沒有必要的,因為每條信息是固定的高度耻陕,所以根據(jù)其是第幾條信息拙徽,再獲取一個list相對頁面頂部的高度,就能得到圖片相對頁面頂部的高度诗宣。我這里每個圖片(100px)算上間隙(40px)就是140px膘怕,只需要獲取整個列表相對頂部的高度,就能得到每個圖片相對頁面頂部的距離召庞。
程序中大概像這樣子:

img_data.push({
        index:(num),
        height:list_height+(140)*(num),
        src:data.src,
        loaded:false //定期清理岛心,加載之后的圖片信息進(jìn)行清除,降低內(nèi)存使用 
      })

視區(qū)的檢測

圖片是否落在用戶視區(qū)篮灼,需要用到以下高度:

  1. height1:document.body.scrollTop:瀏覽器滾動的高度
  2. height2:document.body.clientHeight:可視區(qū)域的高度
  3. height3:node.height:也就是之前獲取到的元素相對頁面頂部的高度(并不是相對可視區(qū)域的頂部)
    當(dāng)height3>heihgt1且height3<height2+height1的時候忘古,可以認(rèn)為這個元素是出現(xiàn)在用戶視區(qū)的,從而將img_data的src賦值給這個塊的img標(biāo)簽诅诱,當(dāng)圖片加載好之后髓堪,opacity配合transition實現(xiàn)動態(tài)的浮現(xiàn)(據(jù)說,人感覺這樣加載的速度更快)娘荡。這一塊大致的代碼如下:
function lazy_load(){
var height1 = document.body.scrollTop+document.body.clientHeight;
  img_data.forEach(function(item){
    if(!item.loaded && item.height>document.body.scrollTop-100 && item.height < height1){
      var img = document.querySelector("img[img-index='"+item.index+"']");
//選擇該圖片
      if(img){
        img.src = item.src;
        item.loaded = true; //下面對img_data進(jìn)行filter的函數(shù)干旁,減少內(nèi)存消耗
        img.onload = function(){
          img.style.opacity = 1;//配合transition可以實現(xiàn)一個漸入的效果
        }
        img.onerror = function(){
          img.style.opacity = 1;
          img.src = '/failed.jpg';//加載失敗,
        }
      }
    }
  img_data = img_data.filter(function(item){
    return !item.loaded;
  })
}

滾動函數(shù)的綁定

直接將上述函數(shù)和window.onscroll進(jìn)行綁定是不太理想的它改,因為滾動函數(shù)的觸發(fā)頻率很高疤孕,而視區(qū)的檢測如果每次滾動都進(jìn)行檢測商乎,那么央拖,一方面造成性能上的損失,一方面鹉戚,似乎所有的圖片都能被檢測到出現(xiàn)在了視區(qū)鲜戒,從而導(dǎo)致所有的圖片都會被加載,并沒有起到懶加載的作用抹凳。所以在這里遏餐,我使用了函數(shù)消抖,原理也不難赢底,網(wǎng)上的實現(xiàn)很多失都,這里給出我的實現(xiàn):

method.debounce = function(func,delay){
  var timer;
  return function(){
    var args = arguments;
    var context = this;
    clearTimeout(timer);
    timer = setTimeout(function(){
      func.apply(this,args);
    },delay);
  }
}

和上述lazy_load結(jié)合柏蘑,進(jìn)行綁定,代碼如下:

var lazy_event = method.debounce(lazy_load,500);//此處500ms可以適當(dāng)縮小
method.addevent(window,'scroll',lazy_event);

和消抖函數(shù)結(jié)合之后粹庞,用戶的滾動不會觸發(fā)lazy_load咳焚,只有當(dāng)用戶停止?jié)L動才會執(zhí)行l(wèi)azy_load,從而達(dá)到圖片懶加載的效果庞溜。

總結(jié)

這次無限滾動革半,我實現(xiàn)了兩種方案:預(yù)加載與圖片懶加載,配合消抖和節(jié)流以及緩存流码,能夠很好的提升頁面性能又官。希望面試的時候能用上吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漫试,一起剝皮案震驚了整個濱河市六敬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驾荣,老刑警劉巖觉阅,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秘车,居然都是意外死亡典勇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門叮趴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來割笙,“玉大人,你說我怎么就攤上這事眯亦∩烁龋” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵妻率,是天一觀的道長乱顾。 經(jīng)常有香客問我,道長宫静,這世上最難降的妖魔是什么走净? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮孤里,結(jié)果婚禮上伏伯,老公的妹妹穿的比我還像新娘。我一直安慰自己捌袜,他們只是感情好说搅,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著虏等,像睡著了一般弄唧。 火紅的嫁衣襯著肌膚如雪适肠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天候引,我揣著相機(jī)與錄音迂猴,去河邊找鬼。 笑死背伴,一個胖子當(dāng)著我的面吹牛沸毁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播傻寂,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼息尺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疾掰?” 一聲冷哼從身側(cè)響起搂誉,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎静檬,沒想到半個月后炭懊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡拂檩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年侮腹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稻励。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡父阻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出望抽,到底是詐尸還是另有隱情加矛,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布煤篙,位于F島的核電站斟览,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏辑奈。R本人自食惡果不足惜苛茂,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望身害。 院中可真熱鬧味悄,春花似錦草戈、人聲如沸塌鸯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丙猬。三九已至涨颜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茧球,已是汗流浹背庭瑰。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留抢埋,地道東北人弹灭。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像揪垄,于是被迫代替她去往敵國和親穷吮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案饥努? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,748評論 1 92
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,079評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫捡鱼、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,094評論 4 62
  • 昨夜 雨聲陣陣酷愧,寒風(fēng)瑟瑟 雷雨交加驾诈、閃電轟鳴,讓人顫栗害怕 冷氣逼人溶浴,讓人感覺冷是從心中鉆出來的乍迄! 這樣的夜 最適...
    流年時光_fe16閱讀 539評論 1 2
  • 《堅持一定就有收獲就乓!》 2017年 3月19日 星期日 晴今天是讀經(jīng)二年零342天,我的日記大樓蓋到1...
    66e1ba940d65閱讀 314評論 0 0