javascript圖片懶加載與預(yù)加載的分析

懶加載與預(yù)加載的基本概念。

懶加載也叫延遲加載:前一篇文章有介紹:JS圖片延遲加載 延遲加載圖片或符合某些條件時(shí)才加載某些圖片。

預(yù)加載:提前加載圖片,當(dāng)用戶需要查看時(shí)可直接從本地緩存中渲染垃帅。

兩種技術(shù)的本質(zhì):兩者的行為是相反的,一個(gè)是提前加載剪勿,一個(gè)是遲緩甚至不加載贸诚。懶加載對(duì)服務(wù)器前端有一定的緩解壓力作用,預(yù)加載則會(huì)增加服務(wù)器前端壓力。

懶加載的意義及實(shí)現(xiàn)方式有:

意義: 懶加載的主要目的是作為服務(wù)器前端的優(yōu)化酱固,減少請(qǐng)求數(shù)或延遲請(qǐng)求數(shù)械念。

實(shí)現(xiàn)方式:

  1.第一種是純粹的延遲加載,使用setTimeOut或setInterval進(jìn)行加載延遲.



2.第二種是條件加載运悲,符合某些條件龄减,或觸發(fā)了某些事件才開(kāi)始異步下載。



3.第三種是可視區(qū)加載班眯,即僅加載用戶可以看到的區(qū)域希停,這個(gè)主要由監(jiān)控滾動(dòng)條來(lái)實(shí)現(xiàn),一般會(huì)在距用戶看到某圖片前一定距離遍開(kāi)始加載署隘,這樣能保證用戶拉下時(shí)正好能看到圖片宠能。

預(yù)加載的意義及實(shí)現(xiàn)方式有:

預(yù)加載可以說(shuō)是犧牲服務(wù)器前端性能,換取更好的用戶體驗(yàn)磁餐,這樣可以使用戶的操作得到最快的反映违崇。實(shí)現(xiàn)預(yù)載的方法非常多,可以用CSS(background)诊霹、JS(Image)羞延、HTML(<img />)都可以。常用的是new Image();脾还,設(shè)置其src來(lái)實(shí)現(xiàn)預(yù)載伴箩,再使用onload方法回調(diào)預(yù)載完成事件。只要瀏覽器把圖片下載到本地荠呐,同樣的src就會(huì)使用緩存赛蔫,這是最基本也是最實(shí)用的預(yù)載方法。當(dāng)Image下載完圖片頭后泥张,會(huì)得到寬和高呵恢,因此可以在預(yù)載前得到圖片的大小(方法是用記時(shí)器輪循寬高變化)。

怎么樣才能實(shí)現(xiàn)預(yù)加載媚创?

我們可以通過(guò)google一搜索:可以看到很多人用這種方式進(jìn)行預(yù)加載:代碼如下:

復(fù)制代碼

function loadImage(url,callback) {

var img = new Image();



img.src = url;

img.onload = function(){

    img.onload = null;

    callback.call(img);

}

}

復(fù)制代碼

在google或者火狐下測(cè)試 都是正常的 不管我怎么刷新都是正常的渗钉,但是在IE6下不是這樣的 我點(diǎn)擊一下 是正常 再次點(diǎn)擊或者重新刷新都不正常。下面的jsfiddle地址:有興趣的同學(xué)可以試試 點(diǎn)擊按鈕后 彈出正常結(jié)果 再次點(diǎn)擊在IE6下就不執(zhí)行onload里面的方法了钞钙,接著重新刷新也不行鳄橘。

想要看效果,點(diǎn)擊我芒炼!

為什么其他瀏覽器正常的:其實(shí)原因很簡(jiǎn)單瘫怜,就是瀏覽器緩存了,除了IE6以外(即說(shuō)opera也會(huì)本刽,但是我特意用opera試了下鲸湃,沒(méi)有赠涮,可能版本的問(wèn)題吧,或許現(xiàn)在已經(jīng)修復(fù)了暗挑。)笋除,其他瀏覽器重新點(diǎn)擊會(huì)再次執(zhí)行onload方法,但是IE6是直接從瀏覽器取的炸裆。

那現(xiàn)在怎么辦垃它?最好的情況是Image可以有一個(gè)狀態(tài)值表明它是否已經(jīng)載入成功了。從緩存加載的時(shí)候烹看,因?yàn)椴恍枰却矗@個(gè)狀態(tài)值就直接是表明已經(jīng)下載了,而從http請(qǐng)求加載時(shí)惯殊,因?yàn)樾枰却螺d贝奇,這個(gè)值顯示為未完成。這樣的話靠胜,就可以搞定了。經(jīng)過(guò)google搜索下即介紹:發(fā)現(xiàn)有一個(gè)為各個(gè)瀏覽器所兼容的Image的屬性——complete毕源。所以浪漠,在圖片onload事件之前先對(duì)這個(gè)值做一下判斷即可。最后霎褐,代碼變成如下的樣子:

復(fù)制代碼

function loadImage(url,callback) {

var img = new Image();



img.src = url;



if(img.complete) {  // 如果圖片已經(jīng)存在于瀏覽器緩存址愿,直接調(diào)用回調(diào)函數(shù)

    

    callback.call(img);

    return; // 直接返回,不用再處理onload事件

}



img.onload = function(){

    img.onload = null;

    callback.call(img);

}

}

復(fù)制代碼

也就是說(shuō)如果圖片已經(jīng)在瀏覽器緩存里面 那么支持直接從瀏覽器緩存取得直接執(zhí)行img.complete里面的函數(shù) 接著返回.

但是我們可以看到上面的代碼:必須等圖片加載完成后冻璃,可以執(zhí)行回調(diào)函數(shù)响谓,也可以說(shuō)等圖片加載后,我們可以獲取圖片的寬度和高度省艳。那么如果我們想提前獲取圖片的尺寸那怎么辦娘纷?上網(wǎng)經(jīng)驗(yàn)告訴我:瀏覽器在加載圖片的時(shí)候你會(huì)看到圖片會(huì)先占用一塊地然后才慢慢加載完畢,并且不需要預(yù)設(shè)width與height屬性跋炕,因?yàn)闉g覽器能夠獲取圖片的頭部數(shù)據(jù)赖晶。基于此辐烂,只需要使用javascript定時(shí)偵測(cè)圖片的尺寸狀態(tài)便可得知圖片尺寸就緒的狀態(tài)遏插。代碼如下:(但是有個(gè)前提是 這個(gè)方式不是我想的,也不是我寫(xiě)的代碼纠修,是網(wǎng)上朋友總結(jié)的代碼 我只是知道有這么一個(gè)原理)

復(fù)制代碼

var imgReady = (function(){

var list = [],

    intervalId = null;



// 用來(lái)執(zhí)行隊(duì)列

var queue = function(){



    for(var i = 0; i < list.length; i++){

        list[i].end ? list.splice(i--,1) : list[i]();

    }

    !list.length && stop();

};



// 停止所有定時(shí)器隊(duì)列

var stop = function(){

    clearInterval(intervalId);

    intervalId = null;

}

return function(url, ready, error) {

    var onready = {}, 

        width, 

        height, 

        newWidth, 

        newHeight,

        img = new Image();

    img.src = url;



    // 如果圖片被緩存胳嘲,則直接返回緩存數(shù)據(jù)

    if(img.complete) {

        ready.call(img);

        return;

    }

    width = img.width;

    height = img.height;



    // 加載錯(cuò)誤后的事件 

    img.onerror = function () {

        error && error.call(img);

        onready.end = true;

        img = img.onload = img.onerror = null;

    };



    // 圖片尺寸就緒

    var onready = function() {

        newWidth = img.width;

        newHeight = img.height;

        if (newWidth !== width || newHeight !== height ||

            // 如果圖片已經(jīng)在其他地方加載可使用面積檢測(cè)

            newWidth * newHeight > 1024

        ) {

            ready.call(img);

            onready.end = true;

        };

    };

    onready();

    // 完全加載完畢的事件

    img.onload = function () {

        // onload在定時(shí)器時(shí)間差范圍內(nèi)可能比onready快

        // 這里進(jìn)行檢查并保證onready優(yōu)先執(zhí)行

        !onready.end && onready();

        // IE gif動(dòng)畫(huà)會(huì)循環(huán)執(zhí)行onload,置空onload即可

        img = img.onload = img.onerror = null;

    };

    

    

    // 加入隊(duì)列中定期執(zhí)行

    if (!onready.end) {

        list.push(onready);

        // 無(wú)論何時(shí)只允許出現(xiàn)一個(gè)定時(shí)器扣草,減少瀏覽器性能損耗

        if (intervalId === null) {

            intervalId = setInterval(queue, 40);

        };

    };

}

})();

復(fù)制代碼

調(diào)用方式如下:

imgReady('http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg',function(){

alert('width:' + this.width + 'height:' + this.height);

});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末了牛,一起剝皮案震驚了整個(gè)濱河市颜屠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌白魂,老刑警劉巖汽纤,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異福荸,居然都是意外死亡蕴坪,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)敬锐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)背传,“玉大人,你說(shuō)我怎么就攤上這事台夺【毒粒” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵颤介,是天一觀的道長(zhǎng)梳星。 經(jīng)常有香客問(wèn)我,道長(zhǎng)滚朵,這世上最難降的妖魔是什么冤灾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辕近,結(jié)果婚禮上韵吨,老公的妹妹穿的比我還像新娘。我一直安慰自己移宅,他們只是感情好归粉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著漏峰,像睡著了一般糠悼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芽狗,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天绢掰,我揣著相機(jī)與錄音,去河邊找鬼童擎。 笑死滴劲,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顾复。 我是一名探鬼主播班挖,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼芯砸!你這毒婦竟也來(lái)了萧芙?” 一聲冷哼從身側(cè)響起给梅,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎双揪,沒(méi)想到半個(gè)月后动羽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渔期,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年运吓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疯趟。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拘哨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出信峻,到底是詐尸還是另有隱情倦青,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布盹舞,位于F島的核電站产镐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏踢步。R本人自食惡果不足惜磷账,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贾虽。 院中可真熱鬧,春花似錦吼鱼、人聲如沸蓬豁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)地粪。三九已至,卻和暖如春琐谤,著一層夾襖步出監(jiān)牢的瞬間蟆技,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工斗忌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留质礼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓织阳,卻偏偏與公主長(zhǎng)得像眶蕉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唧躲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案造挽? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,728評(píng)論 1 92
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評(píng)論 25 707
  • <a name='html'>HTML</a> Doctype作用碱璃?標(biāo)準(zhǔn)模式與兼容模式各有什么區(qū)別? (1)、<...
    clark124閱讀 3,456評(píng)論 1 19
  • 1. 這個(gè)十一,國(guó)內(nèi)的人民踴躍出行堵車歡樂(lè)撒錢(qián)的時(shí)候谐丢,遠(yuǎn)在美國(guó)西岸的華人居民們沒(méi)有長(zhǎng)假可以度過(guò)爽航,卻收到了這樣一條消...
    彼岸沙閱讀 1,022評(píng)論 0 5
  • 街道上越發(fā)寂靜,與此相比庇谆,汽車的行駛聲在暗幕里格外刺耳岳掐。 車一路開(kāi)進(jìn)羅森家的院子里,田小田和丁大力幾乎同時(shí)從車廂左...
    樹(shù)里閱讀 213評(píng)論 0 0