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

Demián Renzulli
Demián Renzulli

在本程式碼研究室中,您將透過兩種方式實作預先載入功能:使用 <link rel="prefetch"> 和 HTTP Link 標頭。

範例應用程式是網站,其中包含宣傳到達網頁,提供商店熱銷 T 恤的特別折扣。由於到達網頁連結至單一產品,因此可以合理推測,有很大比例的使用者會前往產品詳細資料頁面。因此,產品頁面非常適合在到達網頁上預先載入。

評估成效

首先建立基準成效:

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

  5. 在「Throttling」下拉式清單中選取「Fast 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. 如要預覽網站,請按下「View App」。然後按下「Fullscreen」圖示 全螢幕
  2. 按下 `Control+Shift+J` 鍵 (在 Mac 上為 `Command+Option+J` 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。

  4. 在「Throttling」(節流) 下拉式清單中,選取「Fast 3G」(快速 3G) 模擬連線速度緩慢的情況。

  5. 取消勾選「Disable cache」核取方塊。

  6. 重新載入應用程式。

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

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

頁面會保留在 HTTP 快取中五分鐘,之後會套用文件的一般 Cache-Control 規則。在本例中,product-details.html 有一個 cache-control 標頭,其值為 public, max-age=0,表示網頁會保留五分鐘。

重新評估成效

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

請查看「網路」面板。與初始網路追蹤相比,這裡有兩個差異:

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

相較於舊版 (約 600 毫秒),這項功能的執行時間約減少了 98%。

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

額外學分:使用 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 APIeffectiveType 屬性,判斷使用者是否使用 4G (或更快) 連線。
  • 如果符合該條件,系統就會產生 <link> 標記,並將 prefetch 設為提示類型,傳遞 href 屬性中要預先擷取的網址,並指出資源是 as 屬性中的 HTML document
  • 最後,它會在網頁的 head 中動態插入指令碼。

接著,在 views/index.html 結尾 </body> 標記之前,加入 script.js

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

您應該會在「Network」面板中看到 product-details.html

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

如要確認產品頁面不會在連線速度緩慢的情況下預先擷取,請按照下列步驟操作:

  1. 在「節流」下拉式清單中,選取「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. 如要預覽網站,請按下「View App」,然後按下「Fullscreen」全螢幕
  2. 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。
  4. 重新載入應用程式。

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

「Network」面板顯示預先擷取的 style-product.css。

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

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

系統會從「預先擷取快取資料」擷取 style-product.css 檔案,載入時間僅需 12 毫秒。