懶加載和預加載
Motivation
今天做拼多多的前端筆試的時候問到了這樣一個問題:
圖片懶加載和預加載的不同點?他們的應用場景?兩種技術對服務器前端的影響。
好像只是聽說過,沒有具體了解和應用過。所以在這里趕緊總結一下
本文參考了掘金浪里行舟的[懶加載和預加載]https://juejin.im/post/5b0c3b53f265da09253cbed0
懶加載
懶加載也叫延遲加載,指的是在長網頁中延遲加載圖像,是一種很好的優化網頁性能的方式。
用戶滾動到它們之前,可視區域外的圖像不會加載。這與圖像預加載相反,在長網頁上使用延遲加載將使網頁加載更快。
在某些情況下,它還可以幫助減少服務器負載。
懶加載通常適用於圖片很多,頁面很長的電商網站場景中。
懶加載優點有:
- 能提升用戶體驗。例如在使用B站的時候,如果網頁上所有的視頻封面都一次性加載,由於圖片數目較大,等待時間就會很長,嚴重影響用戶體驗。
- 減少無效資源的加載,這樣能明顯減少服務器的壓力和流量,也能夠減少瀏覽器的負擔。
- 防止並發加載的資源過多會阻塞js的加載,影響網站的正常使用。
懶加載的原理:首先將頁面上的src屬性設為空字符串,而圖片的真實路徑則設置在data-original屬性中,當頁面滾動的時候需要監聽scroll事件,在scroll事件的回調中,判斷我們的懶加載的圖片是否進入可視區域,如果圖片在可視區內將圖片的src屬性設置為data-original值,這樣就可以實現延遲加載。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lazyload</title>
<style>
.image-item {
display: block;
margin-bottom: 50px;
height: 200px;//一定記得設置圖片高度
}
</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//獲取可視區高度
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()// 用於獲得頁面中某個元素的左,上,右和下分別相對瀏覽器視窗的位置
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()//剛開始還沒滾動屏幕時,要先觸發一次函數,初始化首頁的頁面圖片
document.addEventListener("scroll",lazyload)
</script>
</body>
</html>
預加載
資源預加載是另一個性能優化技術,可以用來預先告知瀏覽器某些資源可能在將來會被使用到。
預加載就是將所有所需的資源提前請求加載到本地,這樣后面再需要用到時就直接從緩存中獲取資源。
預加載的優點在於:在網頁全部加載之前,對一些主要內容進行加載,以提供給用戶更好的體驗,減少等待的時間。否則,如果一個頁面的內容過於龐大,沒有使用預加載技術的頁面就會長時間的展現為一片空白,直到所有內容加載完畢。
預加載有幾種實現方式:
-
使用HTML標簽
<img src="http://pic26.nipic.com/20121213/lkajf.img" style="display:none">
-
使用image對象
<script src="./myPreload.js"></script>
var image = new Image();
image.src = "http://pic26.nipic.com/20121213/lkajf.img";
- 使用XMLHttpRequest對象,雖然存在跨域問題,但會精細控制預加載過程。
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");
}
}
懶加載和預加載的對比
兩者都是提高頁面性能有效的辦法,兩者主要區別是一個提前加載,一個遲緩甚至不加載。
懶加載對服務器前端有一定的緩解壓力作用,預加載會增加服務器前端壓力。