預先擷取的方法有兩種:<link> 代碼和 HTTP 標頭

德米安 (Demián Renzulli)
Demián Renzulli

在本程式碼研究室中,您將以兩種方式實作預先擷取作業:使用 <link rel="prefetch"> 和 HTTP Link 標頭。

範例應用程式是一個網站,其中的促銷到達網頁提供商店暢銷 T 恤的優惠折扣。由於到達網頁會連結至單一產品,因此安全假設多數使用者都會前往產品詳細資料頁面。這樣一來,就適合在到達網頁上預先擷取產品網頁。

評估效能

首先建立基準成效:

  1. 按一下「Remix to Edit」,讓專案可供編輯。
  2. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕
  3. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  4. 按一下 [網路] 分頁標籤。

  5. 在「Throttling」下拉式清單中,選取「快速 3G」即可模擬連線速度緩慢的類型。

  6. 如要載入產品頁面,請按一下範例應用程式中的「立即購買」

載入 product-details.html 頁面約需 600 毫秒:

顯示 product-details.html 載入時間的網路面板

如要改善瀏覽體驗,請在到達網頁中插入 prefetch 代碼來預先擷取「product-details.html」網頁:

  • 將下列 <link> 元素新增至 views/index.html 檔案的標題:
<!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 為選用屬性,但建議您選用;此屬性可協助瀏覽器設定正確的標頭,並判斷該資源是否已在快取中。這個屬性的值範例包括:documentscriptstylefontimage其他

如何確認預先擷取功能是否正常運作:

  1. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕
  2. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。

  4. 在「Throttling」下拉式清單中,選取「快速 3G」即可模擬連線速度緩慢的類型。

  5. 取消勾選 [停用快取] 核取方塊。

  6. 重新載入應用程式。

現在,當到達網頁載入時,product-details.html 頁面也會載入,但優先順序最低:

顯示 product-details.html 已預先擷取的網路面板。

網頁會保留在 HTTP 快取中 5 分鐘,這段時間過後,系統就會套用文件的一般 Cache-Control 規則。在此情況下,product-details.htmlcache-control 標頭值為 public, max-age=0,表示網頁總共會保留五分鐘。

重新評估成效

  1. 重新載入應用程式。
  2. 如要載入產品頁面,請按一下範例應用程式中的「立即購買」

查看「網路」面板。與初始網路追蹤記錄相比,有以下兩個差異:

  • 「大小」欄顯示「預先擷取快取」,代表這項資源是從瀏覽器快取中擷取,而非網路。
  • 「時間」欄顯示載入文件所需的時間大約是 10 毫秒。

相較於舊版,這個版本大約減少了 98%,約需 600 毫秒。

顯示從預先擷取快取擷取的 product-details.html 網路面板。

額外加分:使用 prefetch 來漸進式強化

如要改善透過快速連線瀏覽網頁的使用者,預先擷取是最佳的實作方式。您可使用 Network Information API 檢查網路狀況,並依據該動態插入的預先擷取代碼。如此一來,您就能盡可能降低資料用量,並為緩慢或昂貴的數據方案使用者節省費用。

如要執行自動調整式預先擷取功能,請先將 <link rel="prefetch"> 標記從 views/index.html 中移除:

<!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 APIeffectiveType 屬性,判斷使用者是否連上 4G (或更快速) 連線。
  • 該條件完成之後,就會產生含有 prefetch 做為提示類型的 <link> 標記,並傳遞將在 href 屬性中預先擷取的網址,並表示資源在 as 屬性中為 HTML document
  • 最後,這個指令碼會以動態方式將指令碼插入網頁的 head

接下來,請將 script.js 新增至 views/index.html,緊接在 </body> 結尾標記前方:

<body>
      ...
      <script src="/script.js"></script>
</body>

在網頁結尾要求 script.js,可確保系統在剖析及載入頁面後會載入並執行頁面。

為確保預先擷取作業不會幹擾目前網頁的重要資源,請加入下列程式碼片段在 window.load 事件上呼叫 injectLinkPrefetchIn4g()

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

到達網頁現在只會透過快速連線預先擷取 product-details.html。驗證方法如下:

  1. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕
  2. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。
  4. 在「Throttling」下拉式清單中,選取「Online」
  5. 重新載入應用程式。

「Network」(網路) 面板中應會顯示 product-details.html

顯示 product-details.html 已預先擷取的網路面板。

如要確認系統是否在連線速度緩慢時預先擷取產品網頁,請按照下列步驟操作:

  1. 在「throttling」下拉式清單中選取「慢 3G」
  2. 重新載入應用程式。

「Network」面板應只包含不含 product-details.html 的到達網頁資源:

顯示 product-details.html 未預先擷取的網路面板。

HTTP Link 標頭可用來預先擷取與 link 標記相同的資源類型。您可以根據自己的偏好,決定使用哪一種廣告的時機,因為成效差異不大。在這種情況下,您將使用此程式碼來預先擷取產品網頁的主要 CSS,進一步改善算繪效果。

在到達網頁的伺服器回應中,為 style-product.css 新增 HTTP Link 標頭:

  1. 開啟 server.js 檔案,然後找出根網址 /get() 處理常式。
  2. 在處理常式的開頭加入下列程式碼:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕
  2. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。
  4. 重新載入應用程式。

系統載入到達網頁後,系統現在會以最低優先順序預先擷取 style-product.css

顯示 style-product.css 已預先擷取的網路面板。

如要前往產品頁面,請按一下「立即購買」。查看「網路」面板:

顯示從預先擷取快取擷取的 style-product.css 網路面板。

系統從「預先擷取快取」中擷取 style-product.css 檔案,因此只需 12 毫秒就能完成載入。