Google 的「加速行動頁面」(AMP) 專案最近幫助影響網站變得更快。憑藉良好的技術和強大的內容分發網絡,Google 直接使 AMP 增強的網站更快。然而,AMP 也透過鼓勵我們查看 AMP 包含的最佳化和最佳實踐來間接發揮作用。即使您不打算讓您的網站相容 AMP,將 AMP 了解為優化非 AMP 網站的待辦事項清單也很有用。
此清單中的最佳化之一是一種稱為「延遲載入」的技術,我們在最近關於使用 AMP 的
延遲載入可以讓訪客更快開始與內容互動,而增強的載入速度可以提高您的搜尋引擎排名。頁面上的圖像越多,獲得的速度提升就越大。
在本教學中,我們將了解如何使用名為的腳本在非 AMP 網站上部署延遲載入Layzr.js。我們將盡可能複製 AMP 的
元素的功能,但我們也將使用 Layzr 特有的一些功能。
我們開始吧!
作為文章「AMP 專案:它會讓您的網站更快嗎?」的一部分我創建了一個包含五個圖像的基本佈局。為了讓您能夠比較使用 AMP 和自己部署延遲加載,我們將重新建立相同的五個映像佈局。我將在本教程後面向您展示如何運行各種加載速度測試。
#在本教學隨附的來源檔案中,您將找到佈局的 AMP 版本,以及您將在此處製作的完整版本。兩者都包含在內,以幫助您決定哪種方法最適合您。
在我們逐步完成所有操作時,我建議您使用Chrome 開發者工具(F12) 測試您的工作,並開啟網路選項卡,選取停用快取,並將限制設為常規3G。這會模擬平均移動連接,向您即時顯示每個圖像加載的圖表,並將幫助您清楚地了解延遲加載的運行情況。
刷新頁面進行測試時,按住重新載入按鈕,這將出現一個下拉式選單會顯示不同的選項。選擇清空快取並硬重新載入以完全模擬訪客首次到達您的網站。
讓我們從基礎知識開始。首先,建立一個資料夾來存放您的項目,並在其中建立一個名為index.html的檔案。
打開它進行編輯並添加以下程式碼:
Layzr.js Lazy Loading Welcome to the lazy loaded web
透過上面的程式碼,我們只是獲得了一個 HTML shell,並包含了一些 CSS,以確保頁面的body
和圖像周圍沒有任何意外的間隙。
我們也包含margin: 0 auto;
,以便我們稍後新增的圖片將會居中。
layzr.js 腳本有兩個方便您載入的 CDN 來源 - 我們將使用來自 Cloudfare 的一個。
將此程式碼新增至您的 html 中,位於結束
標籤之前。
如果您不想從 CDN 載入腳本,您可以下載該腳本並按照以下網址的簡短說明進行操作:https://github.com/callmecavs/layzr.js#download
現在我們已經載入了 Layzr,我們需要讓它在頁面載入時執行。為此,請將此程式碼新增至您剛剛在上一節中插入的script
標記之後:
此程式碼首先建立一個用於包含 Layzr 的實例,然後在載入頁面的 DOM 內容後,它使用該實例來啟動 Layzr 的功能。
到目前為止,您的整體程式碼現在應該如下所示:
Layzr 已載入並準備就緒,我們可以開始添加一些圖像以使其發揮其魔力。您可以使用您想要的任何圖像,但是如果您想使用在以下步驟中看到的確切程式碼範例,您可以下載本教學隨附的來源檔案。在其中您將找到一個images資料夾,您可以將其複製並貼上到您自己的專案中。
要在使用 Layzr 时添加图像,您将使用常规img
元素,但不使用src
属性,而是使用data-normal
像这样:
为了使任何延迟加载脚本正常工作,它需要知道网站上所有图像的高度,以便决定需要加载哪些图像(因为它们位于视口中或靠近视口),以及哪些图像需要加载。应该等待。
然而,棘手的部分是图像在完全加载到页面中之前实际上没有任何高度。这意味着,如果我们希望延迟加载发挥作用,我们需要一种方法在加载图像之前为页面提供有关图像高度的信息。
我们将介绍两种方法来实现这一目标,一种用于固定尺寸图像,另一种用于响应式图像。通过固定大小来赋予图像高度是最简单的方法,因为您只需要添加height
和width
属性。
现在继续,使用data-normal
属性在脚本标记上方添加img
元素,并包括height
和width
,用于您要加载的每个图像。
这种固定大小的方法将允许延迟加载工作,但它会阻止图像响应,这并不理想。稍后我们将介绍如何赋予图像高度和响应能力。
默认情况下,Layzr 只会引入加载时可见的图像。不过,如果也预加载了下一行(位于视口之外)的图像,则访问者可以获得更流畅的体验。
通过在实例化脚本时设置名为threshold
的选项来执行此操作。它的工作方式是您将提供一个表示视口高度百分比的值。如果您将值设置为 100,则表示视口高度的 100%,例如1200 像素。在这种情况下,视口 1200 像素范围内的所有屏幕外内容也会被加载。
例如,如果您有两张大图像,其中一张被推到视口之外,并且您的阈值设置为 100,则两张图像都会加载:
要设置阈值,请在代码中替换此行:
const instance = Layzr()
...这样:
const instance = Layzr({ threshold: 100 })
您可以将此值更改为最适合您创建的网站的值。有趣的是,AMP 的延迟加载阈值似乎大致相当于 200。
Layzr 的一大优点是它可以非常直接地为高分辨率设备添加图像。您所需要做的就是包含属性data-retina
。例如:
更新 HTML 中的所有img
元素以包含视网膜图像,如下所示:
使延迟加载的图像响应起来可能是一个棘手的问题。正如我们之前提到的,为了确定何时加载图像,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
。
现在我们将添加 CSS 以使这一切正常工作。
在index.html文件头中现有的标记之间,添加以下代码:
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%
您可以提前计算所需宽高比的正确百分比,或者如果您愿意,也可以使用 CSScalc()
函数,如上例中注释所示:
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 覆盖。
重新加载浏览器预览并调整视口大小:您现在应该发现所有图像都有响应,同时保留其延迟加载功能,没有回流。
Layzr 还支持 srcset 属性。在支持 srcset 的浏览器中,它将优先于data-normal
和data-retina
使用。
但是,不应使用直接的srcset
属性,而是应该在其前面加上data-
,就像我们迄今为止使用的其他属性一样。
将第一张图像的代码更新为:
要查看此效果,请转到浏览器预览,将视口缩小到 320 像素宽以下,重新加载并观看网络面板。您应该首先看到图像加载的最小版本。然后增加视口的大小,您应该会看到中型和大型版本随您加载。
源文件中提供的图像文件夹包括每个图像的小、中、大版本。更新您的代码以在data-srcset
属性中使用所有这些内容,如下所示:
我们快完成了,但为了创建最后一层润色,我们将添加一个加载动画。这将有助于向访问者传达布局的哪些部分充当图像占位符,以及这些图像正在加载的过程。
我们将使用纯 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; }
现在刷新您的页面,您应该会看到正在运行的加载动画。
完成上述所有操作后,您的代码现在应如下所示:
您现在已经完全手动实现了延迟加载,并且功能与 AMP 尽可能接近。
AMP 会自动执行一些操作,例如处理响应式图像的宽高比保留,但另一方面,您自己执行操作可以实现额外的控制,例如指定您自己的加载阈值。
希望通过此过程可以帮助您决定更喜欢哪种方法。
感谢 Michael Cavalea 提供的出色剧本!要了解有关 Layzr.js 的更多信息,请访问:https://github.com/callmecavs/layzr.js
以上是誰需要 AMP?使用 Layzr.js 簡化延遲載入回應影像的過程的詳細內容。更多資訊請關注PHP中文網其他相關文章!