懶加載也叫延遲加載,指的是在長(zhǎng)網(wǎng)頁(yè)中延遲加載圖像,是一種很好優(yōu)化網(wǎng)頁(yè)性能的方式。用戶滾動(dòng)到它們之前,可視區(qū)域外的圖像不會(huì)加載。這與圖像預(yù)加載相反,在長(zhǎng)網(wǎng)頁(yè)上使用延遲加載將使網(wǎng)頁(yè)加載更快。在某些情況下,它還可以幫助減少服務(wù)器負(fù)載。常適用圖片很多,頁(yè)面很長(zhǎng)的電商網(wǎng)站場(chǎng)景中。
2.為什么要用懶加載
- 能提升用戶的體驗(yàn),不妨設(shè)想下,用戶打開(kāi)像手機(jī)淘寶長(zhǎng)頁(yè)面的時(shí)候,如果頁(yè)面上所有的圖片都需要加載,由于圖片數(shù)目較大,等待時(shí)間很長(zhǎng),用戶難免會(huì)心生抱怨,這就嚴(yán)重影響用戶體驗(yàn)。
- 減少無(wú)效資源的加載,這樣能明顯減少了服務(wù)器的壓力和流量,也能夠減小瀏覽器的負(fù)擔(dān)。
- 防止并發(fā)加載的資源過(guò)多會(huì)阻塞js的加載,影響網(wǎng)站的正常使用。
3.懶加載的原理
首先將頁(yè)面上的圖片的 src 屬性設(shè)為空字符串,而圖片的真實(shí)路徑則設(shè)置在data-original屬性中,
當(dāng)頁(yè)面滾動(dòng)的時(shí)候需要去監(jiān)聽(tīng)scroll事件,在scroll事件的回調(diào)中,判斷我們的懶加載的圖片是否進(jìn)入可視區(qū)域,如果圖片在可視區(qū)內(nèi)將圖片的 src 屬性設(shè)置為data-original 的值,這樣就可以實(shí)現(xiàn)延遲加載。
4.懶加載實(shí)現(xiàn)步驟
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lazyload</title>
<style>
.image-item {
display: block;
margin-bottom: 50px;
height: 200px;//一定記得設(shè)置圖片高度
}
</style>
</head>
<body>
<img src="" class="image-item" lazyload="true" data-original="images/1.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/2.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/3.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/4.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/5.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/6.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/7.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/8.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/9.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/10.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/11.png"/>
<img src="" class="image-item" lazyload="true" data-original="images/12.png"/>
<script>
var viewHeight =document.documentElement.clientHeight//獲取可視區(qū)高度
function lazyload(){
var eles=document.querySelectorAll('img[data-original][lazyload]')
Array.prototype.forEach.call(eles,function(item,index){
var rect
if(item.dataset.original==="")
return
rect=item.getBoundingClientRect()// 用于獲得頁(yè)面中某個(gè)元素的左,上,右和下分別相對(duì)瀏覽器視窗的位置
if(rect.bottom>=0 && rect.top < viewHeight){
!function(){
var img=new Image()
img.src=item.dataset.original
img.onload=function(){
item.src=img.src
}
item.removeAttribute("data-original")//移除屬性,下次不再遍歷
item.removeAttribute("lazyload")
}()
}
})
}
lazyload()//剛開(kāi)始還沒(méi)滾動(dòng)屏幕時(shí),要先觸發(fā)一次函數(shù),初始化首頁(yè)的頁(yè)面圖片
document.addEventListener("scroll",lazyload)
</script>
</body>
</html>
二、預(yù)加載
1.什么是預(yù)加載
資源預(yù)加載是另一個(gè)性能優(yōu)化技術(shù),我們可以使用該技術(shù)來(lái)預(yù)先告知瀏覽器某些資源可能在將來(lái)會(huì)被使用到。預(yù)加載簡(jiǎn)單來(lái)說(shuō)就是將所有所需的資源提前請(qǐng)求加載到本地,這樣后面在需要用到時(shí)就直接從緩存取資源。
2.為什么要用預(yù)加載
在網(wǎng)頁(yè)全部加載之前,對(duì)一些主要內(nèi)容進(jìn)行加載,以提供給用戶更好的體驗(yàn),減少等待的時(shí)間。否則,如果一個(gè)頁(yè)面的內(nèi)容過(guò)于龐大,沒(méi)有使用預(yù)加載技術(shù)的頁(yè)面就會(huì)長(zhǎng)時(shí)間的展現(xiàn)為一片空白,直到所有內(nèi)容加載完畢。
3.實(shí)現(xiàn)預(yù)加載的幾種辦法
- 使用HTML標(biāo)簽
<img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none"/>
- 使用Image對(duì)象
<script src="./myPreload.js"></script>
//myPreload.js文件
var image= new Image()
image.src="http://pic26.nipic.com/20121213/6168183 004444903000 2.jpg"
- 使用XMLHttpRequest對(duì)象,雖然存在跨域問(wèn)題,但會(huì)精細(xì)控制預(yù)加載過(guò)程
var xmlhttprequest=new XMLHttpRequest();
xmlhttprequest.onreadystatechange=callback;
xmlhttprequest.onprogress=progressCallback;
xmlhttprequest.open("GET","http://image.baidu.com/mouse,jpg",true);
xmlhttprequest.send();
function callback(){
if(xmlhttprequest.readyState==4&& xmlhttprequest.status==200){
var responseText=xmlhttprequest.responseText;
}else{
console.log("Request was unsuccessful:"+xmlhttprequest.status);
}
}
function progressCallback(e){
e=e || event;
if(e.lengthComputable){
console.log("Received"+e.loaded+"of"+e.total+"bytes")
}
}
PreloadJS提供了一種預(yù)加載內(nèi)容的一致方式,以便在HTML應(yīng)用程序中使用。預(yù)加載可以使用HTML標(biāo)簽以及XHR來(lái)完成。默認(rèn)情況下,PreloadJS會(huì)嘗試使用XHR加載內(nèi)容,因?yàn)樗峁┝藢?duì)進(jìn)度和完成事件的更好支持,但是由于跨域問(wèn)題,使用基于標(biāo)記的加載可能更好。
//使用preload.js
var queue=new createjs.LoadQueue();//默認(rèn)是xhr對(duì)象,如果是new createjs.LoadQueue(false)是指使用HTML標(biāo)簽,可以跨域
queue.on("complete",handleComplete,this);
queue.loadManifest([
{id:"myImage",src:"http://pic26.nipic.com/20121213/6168183 0044449030002.jpg"},
{id:"myImage2",src:"http://pic9.nipic.com/20100814/2839526 1931471581702.jpg"}
]);
function handleComplete(){
var image=queue.getResuLt("myImage");
document.body.appendChild(image);
}
三、懶加載和預(yù)加載的對(duì)比
兩者都是提高頁(yè)面性能有效的辦法,兩者主要區(qū)別是一個(gè)是提前加載,一個(gè)是遲緩甚至不加載。懶加載對(duì)服務(wù)器前端有一定的緩解壓力作用,預(yù)加載則會(huì)增加服務(wù)器前端壓力。