在本程式碼研究室中,您將透過兩種方式實作預先擷取:使用 <link rel="prefetch">
和使用 HTTP Link
標頭。
範例應用程式是網站,其中包含宣傳到達網頁,提供商店暢銷 T 恤的特別折扣。由於到達網頁會連結至單一產品,因此可以合理推斷,高比例的使用者會前往產品詳細資料頁面。因此,產品頁面很適合在到達網頁上預先擷取。
衡量成效
首先,請建立基準效能:
- 按下 `Control+Shift+J` 鍵 (在 Mac 上為 `Command+Option+J` 鍵) 開啟開發人員工具。
按一下 [網路] 分頁標籤。
在「節流」下拉式清單中,選取「Fast 3G」,模擬連線速度緩慢的情況。
如要載入產品頁面,請在範例應用程式中點選「立即購買」。
product-details.html
頁面載入時間約為 600 毫秒:
使用 <link rel="prefetch">
預先擷取產品頁面
如要改善瀏覽體驗,請在到達網頁中插入 prefetch
標記,預先擷取 product-details.html
網頁:
- 在
views/index.html
檔案的標題中新增下列<link>
元素:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
as
屬性為選用屬性,但建議使用,有助於瀏覽器設定正確的標頭,並判斷資源是否已在快取中。這個屬性的值範例包括:document
、script
、style
、font
、image
和其他。
如要確認預先擷取功能是否正常運作:
- 按下 `Control+Shift+J` 鍵 (在 Mac 上為 `Command+Option+J` 鍵) 開啟開發人員工具。
按一下 [網路] 分頁標籤。
在「節流」下拉式清單中,選取「Fast 3G」,模擬連線速度緩慢的情況。
取消勾選「停用快取」核取方塊。
重新載入應用程式。
現在載入到達網頁時,系統也會載入 product-details.html
網頁,但優先順序最低:
網頁會保留在 HTTP 快取中五分鐘,之後就會套用文件的正常 Cache-Control
規則。在本例中,product-details.html
具有 cache-control
標頭,值為 public, max-age=0
,表示網頁會保留五分鐘。
重新評估成效
- 重新載入應用程式。
- 如要載入產品頁面,請在範例應用程式中點選「立即購買」。
查看「網路」面板。與初始網路追蹤記錄相比,有兩項差異:
- 「大小」欄會顯示「預先擷取快取」,表示這項資源是從瀏覽器的快取而非網路擷取。
- 「時間」欄顯示文件載入時間約為 10 毫秒。
與先前的版本 (約需 600 毫秒) 相比,這項改善措施可減少約 98% 的時間。
加分題:使用 prefetch
進行漸進式強化
建議您將預先擷取功能實作為漸進式強化功能,供使用快速連線瀏覽的使用者使用。您可以使用 Network Information API 檢查網路狀況,並據此動態插入預先擷取標記。這樣一來,使用緩慢或昂貴數據方案的使用者就能盡量減少數據用量,節省費用。
如要導入自適應預先擷取功能,請先從 views/index.html
中移除 <link rel="prefetch">
標記:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
然後在 public/script.js
中加入下列程式碼,宣告函式,在使用者連線速度較快時動態插入 prefetch
代碼:
function injectLinkPrefetchIn4g(url) {
if (window.navigator.connection.effectiveType === '4g') {
//generate link prefetch tag
const linkTag = document.createElement('link');
linkTag.rel = 'prefetch';
linkTag.href = url;
linkTag.as = 'document';
//inject tag in the head of the document
document.head.appendChild(linkTag);
}
}
這項功能的運作方式如下:
- 這項檢查會使用 Network Information API 的 effectiveType 屬性,判斷使用者是否連上 4G (或更快的) 網路。
- 如果符合該條件,系統會產生
<link>
標記,並將prefetch
設為提示類型、在href
屬性中傳遞要預先擷取的網址,以及在as
屬性中指出資源是 HTMLdocument
。 - 最後,系統會將指令碼動態插入網頁的
head
。
接著,在結尾 </body>
標記之前,將 script.js
新增至 views/index.html
:
<body>
...
<script src="/script.js"></script>
</body>
在頁面結尾要求 script.js
,可確保系統在剖析及載入頁面後,再載入及執行 script.js
。
為確保預先擷取不會干擾目前網頁的重要資源,請新增下列程式碼片段,在 window.load
事件中呼叫 injectLinkPrefetchIn4g()
:
<body>
...
<script src="/script.js"></script>
<script>
window.addEventListener('load', () => {
injectLinkPrefetchIn4g('/product-details.html');
});
</script>
</body>
現在,到達網頁只會在連線速度快時預先擷取 product-details.html
。如要確認:
- 按下 `Control+Shift+J` 鍵 (在 Mac 上為 `Command+Option+J` 鍵) 開啟開發人員工具。
- 按一下 [網路] 分頁標籤。
- 在「節流」下拉式清單中,選取「線上」。
- 重新載入應用程式。
「網路」面板中應會顯示 product-details.html
:
如要確認系統不會在連線速度緩慢時預先擷取產品頁面,請按照下列步驟操作:
- 在「節流」下拉式清單中,選取「Slow 3G」(慢速 3G)。
- 重新載入應用程式。
「網路」面板應只包含到達網頁的資源,不含 product-details.html
:
使用 HTTP Link
標頭預先擷取產品頁面的樣式表
HTTP Link
標頭可用於預先擷取與 link
標記相同類型的資源。決定使用哪一個函式大多取決於您的偏好,因為兩者在效能上的差異微不足道。在本例中,您會使用這項功能預先擷取產品頁面的主要 CSS,進一步提升頁面算繪效果。
在到達網頁的伺服器回應中,為 style-product.css
新增 HTTP Link
標頭:
- 開啟
server.js
檔案,然後尋找根網址的get()
處理常式:/
。 - 在處理常式的開頭加入下列程式碼:
app.get('/', function(request, response) {
response.set('Link', '</style-product.css>; rel=prefetch');
response.sendFile(__dirname + '/views/index.html');
});
- 按下 `Control+Shift+J` 鍵 (在 Mac 上為 `Command+Option+J` 鍵) 開啟開發人員工具。
- 按一下 [網路] 分頁標籤。
- 重新載入應用程式。
到達網頁載入後,系統會以最低優先順序預先擷取 style-product.css
:
如要前往產品頁面,請按一下「立即購買」。查看「網路」面板:
系統從「預先擷取快取」中擷取 style-product.css
檔案,載入時間僅 12 毫秒。