Google 的“加速移動頁面”(AMP) 項目最近幫助影響網站變得更快。憑借良好的技術和強大的內容分發網絡,Google 直接使 AMP 增強的網站變得更快。然而,AMP 也通過鼓勵我們查看 AMP 包含的優化和最佳實踐來間接發揮作用。即使您不打算讓您的網站兼容 AMP,將 AMP 了解為優化非 AMP 網站的待辦事項列表也很有用。
此列表中的優化之一是一種稱為“延遲加載”的技術,我們在最近關于使用 AMP 的 自定義元素的文章中看到了該技術的實際應用。通過這種技術,當訪問者首次到達頁面時,僅加載視口中或附近的圖像。當訪問者向下滾動時,其余部分會被觸發加載。
延遲加載可以讓訪問者更快地開始與內容互動,而增強的加載速度可以提高您的搜索引擎排名。頁面上的圖像越多,獲得的速度提升就越大。
在本教程中,我們將了解如何使用名為的腳本在非 AMP 網站上部署延遲加載Layzr.js。我們將盡可能地復制 AMP 的 元素的功能,但我們還將使用 Layzr 特有的一些功能。
我們開始吧!
1. 基本設置
作為文章“AMP 項目:它會讓您的網站更快嗎?”的一部分我創建了一個包含五個圖像的基本布局。為了使您能夠比較使用 AMP 和自己部署延遲加載,我們將重新創建相同的五個圖像布局。我將在本教程后面向您展示如何運行各種加載速度測試。
在本教程附帶的源文件中,您將找到布局的 AMP 版本,以及您將在此處制作的完整版本。兩者都包含在內,以幫助您決定哪種方法最適合您。
在我們逐步完成所有操作時,我建議您使用 Chrome 開發者工具 (F12) 測試您的工作,并打開網絡選項卡,選中禁用緩存 ,并將限制設置為常規 3G。這會模擬平均移動連接,向您實時顯示每個圖像加載的圖表,并將幫助您清楚地了解延遲加載的運行情況。
刷新頁面進行測試時,按住重新加載按鈕,這將出現一個下拉菜單會顯示不同的選項。選擇清空緩存并硬重新加載以完全模擬訪問者首次到達您的網站。
創建 HTML Shell
讓我們從基礎知識開始。首先,創建一個文件夾來存放您的項目,并在其中創建一個名為 index.html 的文件。
打開它進行編輯并添加以下代碼:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Layzr.js Lazy Loading</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style>
body {
margin: 0;
}
img {
display: block;
margin: 0 auto;
}
</style>
</head>
<body>
<h1>Welcome to the lazy loaded web</h1>
</body>
</html>
登錄后復制
通過上面的代碼,我們只是獲得了一個 HTML shell,并包含了一些 CSS,以確保頁面的 body 和圖像周圍沒有任何意外的間隙。
我們還包括 margin: 0 auto; ,以便我們稍后添加的圖像將居中。
加載 Layzr
layzr.js 腳本有兩個方便您加載的 CDN 源 – 我們將使用來自 Cloudfare 的一個。
將此代碼添加到您的 html 中,位于結束 </body> 標記之前。
<script src="https://cdnjs.cloudflare.com/ajax/libs/layzr.js/2.0.2/layzr.min.js"></script>
登錄后復制
如果您不想從 CDN 加載腳本,您可以下載該腳本并按照以下網址的簡短說明進行操作:https://github.com/callmecavs/layzr.js#download
即時 Layzr
現在我們已經加載了 Layzr,我們需要讓它在頁面加載時執行。為此,請將此代碼添加到您剛剛在上一節中插入的 script 標記之后:
<script>
const instance = Layzr()
document.addEventListener('DOMContentLoaded', function(event){
instance.update().check().handlers(true)
})
</script>
登錄后復制
此代碼首先創建一個用于包含 Layzr 的實例,然后在加載頁面的 DOM 內容后,它使用該實例來激活 Layzr 的功能。
到目前為止,您的整體代碼現在應如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Layzr.js Lazy Loading</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style>
body {
margin: 0;
}
img {
display: block;
margin: 0 auto;
}
</style>
</head>
<body>
<h1>Welcome to the lazy loaded web</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/layzr.js/2.0.2/layzr.min.js"></script>
<script>
const instance = Layzr()
document.addEventListener('DOMContentLoaded', function(event){
instance.update().check().handlers(true)
})
</script>
</body>
</html>
登錄后復制
2. 添加圖像(正常分辨率)
Layzr 已加載并準備就緒,我們可以開始添加一些圖像以使其發揮其魔力。您可以使用您想要的任何圖像,但是如果您想使用在以下步驟中看到的確切代碼示例,您可以下載本教程附帶的源文件。在其中您將找到一個 images 文件夾,您可以將其復制并粘貼到您自己的項目中。
要在使用 Layzr 時添加圖像,您將使用常規 img 元素,但不使用 src 屬性,而是使用 data-normal 像這樣:
<img data-normal="images/vulture.jpg" alt="Vulture">
登錄后復制
確保圖像具有高度
為了使任何延遲加載腳本正常工作,它需要知道網站上所有圖像的高度,以便決定需要加載哪些圖像(因為它們位于視口中或靠近視口),以及哪些圖像需要加載。應該等待。
然而,棘手的部分是圖像在完全加載到頁面中之前實際上沒有任何高度。這意味著,如果我們希望延遲加載發揮作用,我們需要一種方法在加載圖像之前為頁面提供有關圖像高度的信息。
我們將介紹兩種方法來實現這一目標,一種用于固定尺寸圖像,另一種用于響應式圖像。通過固定大小來賦予圖像高度是最簡單的方法,因為您只需要添加 height 和 width 屬性。
<img data-normal="images/vulture.jpg" alt="Vulture" height="640" width="960">
登錄后復制
現在繼續,使用 data-normal 屬性在腳本標記上方添加 img 元素,并包括 height 和width,用于您要加載的每個圖像。
<img data-normal="images/vulture.jpg" alt="Vulture" height="640" width="960">
<img data-normal="images/beach.jpg" alt="Beach" height="640" width="960">
<img data-normal="images/bear.jpg" alt="Bear" height="640" width="960">
<img data-normal="images/sky.jpg" alt="Sky" height="540" width="960">
<img data-normal="images/bike.jpg" alt="Bike" height="540" width="960">
登錄后復制
這種固定大小的方法將允許延遲加載工作,但它會阻止圖像響應,這并不理想。稍后我們將介紹如何賦予圖像高度和響應能力。
3.設置加載閾值
默認情況下,Layzr 只會引入加載時可見的圖像。不過,如果也預加載了下一行(位于視口之外)的圖像,則訪問者可以獲得更流暢的體驗。
通過在實例化腳本時設置名為 threshold 的選項來執行此操作。它的工作方式是您將提供一個表示視口高度百分比的值。如果您將值設置為 100,則表示視口高度的 100%,例如1200 像素。在這種情況下,視口 1200 像素范圍內的所有屏幕外內容也會被加載。
例如,如果您有兩張大圖像,其中一張被推到視口之外,并且您的閾值設置為 100,則兩張圖像都會加載:
要設置閾值,請在代碼中替換此行:
const instance = Layzr()
登錄后復制
…這樣:
const instance = Layzr({
threshold: 100
})
登錄后復制
您可以將此值更改為最適合您創建的網站的值。有趣的是,AMP 的延遲加載閾值似乎大致相當于 200。
4. 添加 Retina/HiDPI 圖像
Layzr 的一大優點是它可以非常直接地為高分辨率設備添加圖像。您所需要做的就是包含屬性 data-retina。例如:
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" height="640" width="960">
登錄后復制
更新 HTML 中的所有 img 元素以包含視網膜圖像,如下所示:
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" height="640" width="960"> <img data-normal="images/beach.jpg" data-retina="images/[email protected]" alt="Beach" height="640" width="960"> <img data-normal="images/bear.jpg" data-retina="images/[email protected]" alt="Bear" height="640" width="960"> <img data-normal="images/sky.jpg" data-retina="images/[email protected]" alt="Sky" height="540" width="960"> <img data-normal="images/bike.jpg" data-retina="images/[email protected]" alt="Bike" height="540" width="960">
登錄后復制
5.響應式圖像占位符和回流預防
使延遲加載的圖像響應起來可能是一個棘手的問題。正如我們之前提到的,為了確定何時加載圖像,Layzr 首先需要知道它們的高度。由于響應式圖像的尺寸一直在變化,因此它們的高度是不可預測的。
除此之外,我們還希望在頁面布局中添加一些內容來防止回流。重排是指當圖像完成加載并從沒有大小到突然占用布局中的空間,導致其周圍的所有內容移動時發生的情況。對于試圖關注您的內容卻讓內容在他們的頁面上跳轉的訪問者來說,這可能會非常令人沮喪。
我們可以通過在頁面中為每張圖片提供正確尺寸的響應式占位符來解決這兩個問題。占位符將確保頁面布局不需要重排,并且還將為 Layzr 提供可使用的高度。我們的方法將基于 Thierry Koblentz 撰寫的這篇關于“創建視頻內在比率”的“A List Apart”文章中的巧妙技術。
唯一的條件是您需要提前知道發布的每個圖像的寬高比,因為 CSS 會根據指定的寬高比調整圖像的大小。
添加縱橫比包裝器
我們要做的第一件事是在我們的第一個圖像周圍添加一個 div 包裝器 – 這個 div 將成為我們的占位符。我們將使用 CSS 調整 div 本身的大小,然后設置其中的圖像以水平和垂直填充它。
我們將為 div 提供一個類名,表示它將包含的圖像的寬高比。在我們的示例中,第一張圖像的寬度為 960 像素,高度為 640 像素,所以讓我們弄清楚它的長寬比是多少。
640(我們的高度)是 960(我們的寬度)的三分之二,這意味著每 2 個單位的高度,圖像就有 3 個單位的寬度。寬高比通常表示為 width:height,如眾所周知的 16:9。我們的第一個示例圖像的比例是 3:2。
為了表示此寬高比,我們將為包裝器 div 指定類名稱 ratio_3_2。
<div class="ratio_3_2">
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" height="640" width="960">
</div>
登錄后復制
添加標準寬高比樣式
現在我們將添加 CSS 以使這一切正常工作。
在 index.html 文件頭中現有的 <style></style> 標記之間,添加以下代碼:
div[class^="ratio_"]{
position: relative;
width: 100%;
}
登錄后復制
此選擇器將選取我們的 ratio_3_2 類,但它也會選取以 ratio_ 開頭的任何其他類。這意味著我們可以稍后創建更多類來適應不同的寬高比。
在這種樣式中,我們確保包裝器始終拉伸到其父寬度的 100%。我們還將其設置為 position:relative;,因為這會將圖像絕對定位在其中 – 稍后您就會明白原因。
給出縱橫比包裝高度
現在我們將僅添加特定于我們的 ratio_3_2 類的代碼:
.ratio_3_2 {
/*padding-top: calc( 100% * (2 / 3) );*/
padding-top: 66.666667%;
}
登錄后復制
padding-top 值允許我們將包裝 div 保持在我們想要的寬高比。無論 div 的寬度是多少,此填充都會將高度保持在該寬度的 66.666667%(三分之二),從而保持 3:2 的寬高比。
要確定此處放置的百分比,請計算以寬度百分比表示的縱橫比的高度。您可以通過計算來做到這一點:
100% *(高度/寬度)
對于我們的 3:2 比例來說:100% * (2 / 3) =?66.666667%
您可以提前計算所需寬高比的正確百分比,或者如果您愿意,也可以使用 CSS calc() 函數,如上例中注釋所示:
padding-top: calc( 100% * (2 / 3) );
用圖像填充縱橫比包裝器
無論視口寬度如何,我們的縱橫比包裝器現在都將保持所需的尺寸。所以現在我們要做的就是讓其中包含的圖像填充包裝器,從而繼承它的尺寸。
我們將通過絕對定位嵌套在 ratio_ 類包裝器 div 內的任何圖像來實現此目的,將其放置在包裝器的左上角,然后拉伸其高度和寬度均為 100%,如下所示:
div[class^="ratio_"] > img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
登錄后復制
檢查您的第一張圖像,您現在應該看到它拉伸到視口的寬度,但在調整大小時會縮小以適應,并始終保持其縱橫比。
添加額外的縱橫比
您可能擁有各種不同長寬比的圖像,并且您希望能夠適應它們。在本教程中我們使用的示例圖像中,前三個圖像的縱橫比為 3:2,但第四個和第五個圖像的縱橫比為 16:9。
為了解決這個問題,請添加一個根據寬高比命名的新類,即 ratio_16_9,以及相應的 padding-top 值:
.ratio_16_9 {
/*padding-top: calc( 100% * (9 / 16) );*/
padding-top: 56.25%;
}
登錄后復制
繼續在所有其余圖像周圍添加寬高比 div 包裝器,根據每個圖像的大小使用適當的類。您還可以從圖像中刪除 height 和 width 屬性,因為它們現在都將被我們的 CSS 覆蓋。
<div class="ratio_3_2">
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture">
</div>
<div class="ratio_3_2">
<img data-normal="images/beach.jpg" data-retina="images/[email protected]" alt="Beach">
</div>
<div class="ratio_3_2">
<img data-normal="images/bear.jpg" data-retina="images/[email protected]" alt="Bear">
</div>
<div class="ratio_16_9">
<img data-normal="images/sky.jpg" data-retina="images/[email protected]" alt="Sky">
</div>
<div class="ratio_16_9">
<img data-normal="images/bike.jpg" data-retina="images/[email protected]" alt="Bike">
</div>
登錄后復制
重新加載瀏覽器預覽并調整視口大小:您現在應該發現所有圖像都有響應,同時保留其延遲加載功能,沒有回流。
6.添加srcset
Layzr 還支持 srcset 屬性。在支持 srcset 的瀏覽器中,它將優先于 data-normal 和 data-retina
使用。
但是,不應使用直接的 srcset 屬性,而是應該在其前面加上 data- ,就像我們迄今為止使用的其他屬性一樣。
將第一張圖像的代碼更新為:
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" data-srcset="images/vulture_sml.jpg 320w, images/vulture_med.jpg 640w, images/vulture.jpg 960w">
登錄后復制
要查看此效果,請轉到瀏覽器預覽,將視口縮小到 320 像素寬以下,重新加載并觀看網絡面板。您應該首先看到圖像加載的最小版本。然后增加視口的大小,您應該會看到中型和大型版本隨您加載。
源文件中提供的圖像文件夾包括每個圖像的小、中、大版本。更新您的代碼以在 data-srcset 屬性中使用所有這些內容,如下所示:
<div class="ratio_3_2">
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" data-srcset="images/vulture_sml.jpg 320w, images/vulture_med.jpg 640w, images/vulture.jpg 960w">
</div>
<div class="ratio_3_2">
<img data-normal="images/beach.jpg" data-retina="images/[email protected]" alt="Beach" data-srcset="images/beach_sml.jpg 320w, images/beach_med.jpg 640w, images/beach.jpg 960w">
</div>
<div class="ratio_3_2">
<img data-normal="images/bear.jpg" data-retina="images/[email protected]" alt="Bear" data-srcset="images/bear_sml.jpg 320w, images/bear_med.jpg 640w, images/bear.jpg 960w">
</div>
<div class="ratio_16_9">
<img data-normal="images/sky.jpg" data-retina="images/[email protected]" alt="Sky" data-srcset="images/sky_sml.jpg 320w, images/sky_med.jpg 640w, images/sky.jpg 960w">
</div>
<div class="ratio_16_9">
<img data-normal="images/bike.jpg" data-retina="images/[email protected]" alt="Bike" data-srcset="images/bike_sml.jpg 320w, images/bike_med.jpg 640w, images/bike.jpg 960w">
</div>
登錄后復制
添加加載動畫
我們快完成了,但為了創建最后一層潤色,我們將添加一個加載動畫。這將有助于向訪問者傳達布局的哪些部分充當圖像占位符,以及這些圖像正在加載的過程。
我們將使用純 CSS 加載器,這是 Alan Shortis 編寫的這款出色筆的略微修改版本:https://codepen.io/alanshortis/pen/eJLVXr
為了避免需要任何額外的標記,我們將把加載動畫包含在附加到每個寬高比包裝器的 :after psuedo 元素中。將以下內容添加到您的 CSS 中:
div[class^="ratio_"]:after {
content: '';
display: block;
width: 3rem;
height: 3rem;
border-radius: 50%;
border: .5rem double #444;
border-left: .5rem double white;
position: absolute;
top: calc(50% - 2rem);
left: calc(50% - 2rem);
animation: spin 0.75s infinite linear;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
登錄后復制
上面的代碼創建了一個小圓形加載器圖標,將其居中,并使其每 0.75 秒旋轉 360 度。
我們還將在長寬比包裝器中添加深灰色背景顏色,以便輕松將它們與布局的其余部分區分開來。添加此 background-color: #333;?行,如下所示:
div[class^="ratio_"]{
position: relative;
width: 100%;
background-color: #333;
}
登錄后復制
最后,我們只需要確保我們的加載程序不會將自身定位在圖像的頂部。為此,我們將行 z-index: 1; 添加到我們的圖像中,將它們移動到加載器頂部的一層:
div[class^="ratio_"] > img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
登錄后復制
現在刷新您的頁面,您應該會看到正在運行的加載動畫。
您的最終代碼
完成上述所有操作后,您的代碼現在應如下所示:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Layzr.js Lazy Loading</title>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style>
body {
margin: 0;
}
img {
display: block;
margin: 0 auto;
}
div[class^="ratio_"]{
position: relative;
width: 100%;
background-color: #333;
}
.ratio_3_2 {
/*padding-top: calc( 100% * (2 / 3) );*/
padding-top: 66.666667%;
}
.ratio_16_9 {
/*padding-top: calc( 100% * (9 / 16) );*/
padding-top: 56.25%;
}
div[class^="ratio_"] > img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
div[class^="ratio_"]:after {
content: '';
display: block;
width: 3rem;
height: 3rem;
border-radius: 50%;
border: .5rem double #444;
border-left: .5rem double white;
position: absolute;
top: calc(50% - 2rem);
left: calc(50% - 2rem);
animation: spin 0.75s infinite linear;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<h1>Welcome to the lazy loaded web</h1>
<div class="ratio_3_2">
<img data-normal="images/vulture.jpg" data-retina="images/[email protected]" alt="Vulture" data-srcset="images/vulture_sml.jpg 320w, images/vulture_med.jpg 640w, images/vulture.jpg 960w">
</div>
<div class="ratio_3_2">
<img data-normal="images/beach.jpg" data-retina="images/[email protected]" alt="Beach" data-srcset="images/beach_sml.jpg 320w, images/beach_med.jpg 640w, images/beach.jpg 960w">
</div>
<div class="ratio_3_2">
<img data-normal="images/bear.jpg" data-retina="images/[email protected]" alt="Bear" data-srcset="images/bear_sml.jpg 320w, images/bear_med.jpg 640w, images/bear.jpg 960w">
</div>
<div class="ratio_16_9">
<img data-normal="images/sky.jpg" data-retina="images/[email protected]" alt="Sky" data-srcset="images/sky_sml.jpg 320w, images/sky_med.jpg 640w, images/sky.jpg 960w">
</div>
<div class="ratio_16_9">
<img data-normal="images/bike.jpg" data-retina="images/[email protected]" alt="Bike" data-srcset="images/bike_sml.jpg 320w, images/bike_med.jpg 640w, images/bike.jpg 960w">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/layzr.js/2.0.2/layzr.min.js"></script>
<script>
const instance = Layzr()
document.addEventListener('DOMContentLoaded', function(event){
instance.update().check().handlers(true)
})
</script>
</body>
</html>
登錄后復制
總結
您現在已經完全手動實現了延遲加載,并且功能與 AMP 盡可能接近。
AMP 會自動執行一些操作,例如處理響應式圖像的寬高比保留,但另一方面,您自己執行操作可以實現額外的控制,例如指定您自己的加載閾值。
希望通過此過程可以幫助您決定更喜歡哪種方法。
感謝 Michael Cavalea 提供的出色劇本!要了解有關 Layzr.js 的更多信息,請訪問:https://github.com/callmecavs/layzr.js
以上就是誰需要 AMP?使用 Layzr.js 簡化延遲加載響應圖像的過程的詳細內容,更多請關注www.92cms.cn其它相關文章!






