在 Chrome 中預先算繪頁面,讓使用者能夠快速瀏覽網頁

發布日期:2022 年 12 月 2 日,上次更新日期:2025 年 8 月 17 日

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

Source

Chrome 團隊已恢復完整預先算繪使用者可能前往的網頁。

預先算繪簡史

過去 Chrome 支援 <link rel="prerender" href="/next-page"> 資源提示,但 Chrome 以外的瀏覽器並未廣泛支援,而且這項 API 的表達能力不佳。

使用連結 rel=prerender 提示的舊版預先算繪功能已遭淘汰,取而代之的是 NoState Prefetch,這項功能會擷取未來網頁所需的資源,但不會完整預先算繪網頁或執行 JavaScript。無狀態預先擷取功能可改善資源載入作業,進而提升網頁效能,但無法像完整預先算繪功能一樣,立即載入網頁。

Chrome 團隊現在已在 Chrome 中重新導入完整預先算繪功能。為避免現有使用情形發生問題,並為日後擴充預先算繪功能預留空間,這項新的預先算繪機制不會使用 <link rel="prerender"...> 語法,這項語法仍會用於無狀態預先擷取,但日後可能會淘汰。

網頁預先算繪的運作方式

網頁可透過四種方式預先算繪,目的都是為了加快瀏覽速度:

  1. 當您在 Chrome 網址列 (又稱「網址列」) 中輸入網址時,如果 Chrome 根據您先前的瀏覽記錄,高度確信您會造訪該網頁,就會自動預先算繪網頁。
  2. 使用書籤列時,只要將指標懸停在其中一個書籤按鈕上,Chrome 就可能會自動預先算繪頁面。
  3. 在 Chrome 網址列中輸入搜尋字詞時,Chrome 可能會根據搜尋引擎的指示,自動預先算繪搜尋結果頁面。
  4. 網站可以使用 Speculation Rules API,以程式輔助方式告知 Chrome 要預先算繪哪些網頁。這項功能會取代 <link rel="prerender"...> 的用途,讓網站能根據網頁上的推測規則,主動預先算繪網頁。這些屬性可以靜態存在於網頁上,也可以由 JavaScript 動態插入,視網頁擁有者需求而定。

在這些情況下,預先算繪的行為就像是在隱形背景分頁中開啟網頁,然後透過將前景分頁替換為該預先算繪的網頁來「啟用」。如果網頁在完全預先算繪前啟動,目前狀態為「前景化」,並會繼續載入,表示您仍可獲得良好的開端。

由於預先算繪的網頁是以隱藏狀態開啟,因此許多會造成侵入性行為的 API (例如提示) 不會在這個狀態下啟動,而是會延遲到網頁啟動時才啟動。在少數情況下,如果無法預先算繪,系統會取消預先算繪作業。Chrome 團隊正努力將預先算繪取消原因公開為 API,並強化開發人員工具功能,讓識別這類極端情況更加容易。

預先算繪的影響

預先算繪可讓網頁近乎即時載入,如下方影片所示:

預先算繪的影響範例。

範例網站的速度已經很快,但您仍可看出預先算繪如何提升使用者體驗。因此,這也會直接影響網站的網站體驗核心指標,因為 LCP 接近零、CLS 減少 (任何載入 CLS 都會在初始檢視畫面之前發生),且 INP 改善 (載入應在使用者互動前完成)。

即使網頁在完全載入前啟動,網頁載入作業的領先優勢仍應能提升載入體驗。如果在預先算繪期間啟動連結,預先算繪的網頁會移至主要頁框,並繼續載入。

不過,預先算繪會耗用額外的記憶體和網路頻寬。請注意不要過度預先算繪,以免耗用使用者資源。只有在使用者很可能前往該網頁時,才預先轉譯網頁。

如要進一步瞭解如何在 Analytics 中評估實際成效影響,請參閱「評估成效」一節。

查看 Chrome 網址列預測

在第一個用途中,您可以在 chrome://predictors 頁面中查看 Chrome 對網址的預測:

Chrome 預測工具頁面經過篩選,根據輸入的文字顯示低 (灰色)、中 (琥珀色) 和高 (綠色) 預測結果。
Chrome Predictors 頁面。

綠線表示有足夠的信心觸發預先算繪。在本例中,輸入「s」會產生合理的信心度 (琥珀色),但輸入「sh」後,Chrome 就有足夠的信心,判斷您幾乎都會前往 https://sheets.google.com

這張螢幕截圖是在相對較新的 Chrome 安裝版本中拍攝,並已過濾掉信賴度為零的預測結果,但如果您查看自己的預測結果,可能會看到更多項目,且可能需要更多字元才能達到足夠高的信賴度。

這些預測因子也會驅動您可能注意到的網址列建議選項:

Chrome 網址列的「自動完成」功能
網址列「自動完成」功能。

Chrome 會根據你的輸入內容和選取項目,持續更新預測內容。

  • 如果信心指數超過 50% (以琥珀色顯示),Chrome 會主動預先連線至網域,但不會預先算繪網頁。
  • 如果信賴度超過 80% (以綠色顯示),Chrome 就會預先算繪網址。

Speculation Rules API

如果是 Speculation Rules API 的預先算繪選項,網頁開發人員可以在網頁上插入 JSON 指令,告知瀏覽器要預先算繪哪些網址:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

或是透過文件規則 (適用於 Chrome 121 以上版本),根據 href 選取器 (以 URL Pattern API 為依據) 或 CSS 選取器,預先算繪文件中找到的連結:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/wp-admin"}},
        { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
        { "not": {"selector_matches": ".do-not-prerender"}},
        { "not": {"selector_matches": "[rel~=nofollow]"}}
      ]
    }
  }]
}
</script>

Chrome 團隊準備了 Speculation Rules 程式碼研究室,逐步說明如何將 Speculation Rules 新增至網站。

Eagerness

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Source

eagerness 設定用於指出推測應觸發的時間,特別適用於文件規則:

  • immediate用於盡快推測,亦即發現推測規則時就開始推測。
  • eager這個屬性原本的行為與 immediate 完全相同,但自 Chrome 141 起,將變更為 5 公釐的懸停,並預計在行動裝置上進一步變更為簡單的可視區域啟發式方法
  • moderate在桌機上,如果您將游標懸停在連結上 200 毫秒,或者發生 pointerdown 事件 (以較快者為準,在行動裝置上沒有 hover 事件),那麼就執行推測。在行動裝置上,我們將根據複雜的可視區域啟發式演算法推出這項異動。
  • conservative在點下游標或觸碰時推測。

list 規則的預設 eagernessimmediatemoderateconservative 選項可用於將 list 規則限制為使用者與特定清單互動的網址。不過在許多情況下,使用適當 where 條件的 document 規則可能更合適。

document 規則的預設 eagernessconservative。由於文件可能包含許多網址,因此使用 immediateeager 建立 document 規則時,請務必謹慎 (另請參閱下方的「Chrome 限制」一節)。

請根據網站選擇要使用的 eagerness 設定。如果是輕量型靜態網站,積極推測的成本可能不高,且對使用者有益。如果網站架構較複雜,網頁有效負載較重,建議您減少預測次數,直到使用者提供更多正向意圖信號,藉此減少浪費。

moderate 選項是中間地帶,許多網站都能受益於下列推測規則,只要將指標懸停在連結上 200 毫秒,或在 pointerdown 事件上,即可預先算繪連結,做為推測規則的基本但功能強大的實作方式:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "moderate"
  }]
}
</script>

預先擷取

推測規則也可以只用於預先擷取網頁,而不進行完整預先算繪。這通常是預先算繪的第一步:

<script type="speculationrules">
{
  "prefetch": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Chrome 限制

Chrome 設有限制,可避免過度使用 Speculation Rules API:

熱切 預先擷取 預先算繪
immediate/eager 50 10
moderate/conservative 2 (FIFO) 2 (FIFO)
Chrome 中的推測限制。

moderateconservative 設定 (取決於使用者互動) 會先進先出 (FIFO):達到上限後,新的推測會導致最舊的推測遭到取消,並由較新的推測取代,以節省記憶體。取消預測後,系統會再次觸發預測 (例如再次將游標懸停在該連結上),導致系統重新預測該網址,並推出最舊的預測。在這種情況下,先前的推測會將該網址的所有可快取資源快取到 HTTP 快取中,因此進一步推測應可降低成本。因此,我們將上限設為 2 個,這個門檻並不高。靜態清單規則不會因使用者動作而觸發,因此上限較高,因為瀏覽器無法判斷需要哪些規則,以及何時需要。

immediateeager 的限制也是動態的,因此移除 list 網址指令碼元素,即可取消這些移除的推測,進而建立容量。

Chrome 也會在特定情況下禁止使用推測,包括:

  • Save-Data
  • 節能模式:啟用後,裝置會在電量不足時開啟節能模式。
  • 記憶體限制。
  • 「預先載入網頁」設定關閉時 (Chrome 擴充功能 (例如 uBlock Origin) 也會明確關閉這項設定)。
  • 在背景分頁中開啟的網頁。

此外,在啟動之前,Chrome 也不會在預先算繪的網頁上算繪跨來源 iframe。

這些條件的目標是減少過度投機的影響,避免對使用者造成損害。

如何在網頁中加入推測規則

推測規則可以靜態方式納入網頁的 HTML 中,也可以透過 JavaScript 動態插入網頁:

  • 靜態納入的推測規則:舉例來說,如果新聞媒體網站或網誌的大部分使用者經常會前往最新文章,網站或網誌可以預先算繪該文章。或者,您也可以使用含有 moderateconservative 的文件規則,在使用者與連結互動時進行推測。
  • 動態插入的推測規則:這類規則可能根據應用程式邏輯、使用者個人化設定或其他啟發式方法。

如果偏好根據動作 (例如將游標懸停在連結上或點按連結) 動態插入內容 (許多程式庫過去都使用 <link rel=prefetch> 這麼做),建議查看文件規則,因為這些規則可讓瀏覽器處理許多用途。

您可以在主要框架的 <head><body> 中新增推測規則。系統不會對子框架中的推測規則採取行動,且只會在預先算繪的網頁啟用後,對其中的推測規則採取行動。

Speculation-Rules HTTP 標頭

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Source

您也可以使用 Speculation-Rules HTTP 標頭傳送推測規則,不必直接將規則納入文件的 HTML 中。這樣一來,CDN 就能更輕鬆地部署,不必變更文件內容本身。

Speculation-Rules HTTP 標頭會連同文件一併傳回,並指向包含推測規則的 JSON 檔案位置:

Speculation-Rules: "/speculationrules.json"

這個資源必須使用正確的 MIME 類型,如果是跨來源資源,則必須通過 CORS 檢查。

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

如要使用相對網址,建議在推測規則中加入 "relative_to": "document" 鍵。否則,相對網址會相對於推測規則 JSON 檔案的網址。如果您需要選取部分或所有同源連結,這項功能就特別實用。

推測規則標記欄位

Browser Support

  • Chrome: 136.
  • Edge: 136.
  • Firefox: not supported.
  • Safari: not supported.

Source

您也可以在個別規則層級的推測規則 JSON 語法中新增「標記」:

{
  "prefetch": [
    "urls": ["next.html"],
    "tag": "my-prefetch-rules"
  ],
  "prerender": [
    "urls": ["next2.html"],
    "tag": "my-prerender-rules"
  ],
}

或在規則集的所有推測規則的整體層級:

{
  "tag": "my-rules",
  "prefetch": [
    "urls": ["next.html"]
  ],
  "prerender": [
    "urls": ["next2.html"]
  ],
}

這個標記隨後會反映在 Sec-Speculation-Tags HTTP 標頭中,可用於在伺服器端篩選推測規則。如果推測結果符合多項規則,Sec-Speculation-Tags HTTP 標頭可以包含多個標記,如下例所示:

Sec-Speculation-Tags: null
Sec-Speculation-Tags: null, "cdn-prefetch"
Sec-Speculation-Tags: "my-prefetch-rules"
Sec-Speculation-Tags: "my-prefetch-rules", "my-rules", "cdn-prefetch"

部分 CDN 會自動插入推測規則,但會封鎖非邊緣快取網頁的推測,避免這項功能導致來源伺服器用量增加。標記可讓他們識別預設規則集啟動的推測,但仍允許網站新增的任何規則傳遞至來源。

標記在工具中也可能很有用,例如我們打算在開發人員工具中新增標記

推測規則 target_hint 欄位

Browser Support

  • Chrome: 138.
  • Edge: 138.
  • Firefox: not supported.
  • Safari: not supported.

Source

推測規則也可以包含 target_hint 欄位,其中包含有效的瀏覽環境名稱或關鍵字,指出網頁預期啟動預先算繪內容的位置:

<script type=speculationrules>
{
  "prerender": [{
    "target_hint": "_blank",
    "urls": ["next.html"]
  }]
}
</script>

這項提示可處理 target="_blank" 連結的預先算繪推測:

<a target="_blank" href="next.html">Open this link in a new tab</a>

目前 Chrome 僅支援 "target_hint": "_blank""target_hint": "_self" (如果未指定,則為預設值),且僅適用於預先算繪,不支援預先擷取。

target_hint 僅適用於 urls 推測規則,因為文件規則的 target 是從連結本身得知。

推測規則和 SPA

推測規則僅支援由瀏覽器管理的全頁面瀏覽,不支援單頁應用程式 (SPA) 或應用程式殼層頁面。這些架構不會擷取文件,而是擷取資料或網頁的 API 或部分內容,然後在目前網頁中處理及呈現。應用程式可在推測規則外預先擷取這些所謂「軟性導覽」所需的資料,但無法預先算繪。

推測規則可用於從上一個頁面預先算繪應用程式本身。這有助於抵銷部分單頁應用程式的額外初始載入費用。不過,應用程式內的路線變更無法預先算繪。

對推測規則執行偵錯

請參閱偵錯推測規則的專文,瞭解 Chrome 開發人員工具的新功能,協助查看及偵錯這項新 API。

多個推測規則

您也可以在同一網頁中新增多項推測規則,這些規則會附加至現有規則。因此,以下不同方式都會導致 one.htmltwo.html 預先算繪:

網址清單:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html", "two.html"]
    }
  ]
}
</script>

多個 speculationrules 指令碼:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    }
  ]
}
</script>
<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

一組 speculationrules 內有多個清單

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    },
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

Browser Support

  • Chrome: 127.
  • Edge: 127.
  • Firefox: not supported.
  • Safari: not supported.

Source

預先擷取或預先算繪網頁時,某些網址參數 (技術上稱為搜尋參數) 對伺服器實際提供的網頁可能並不重要,只會由用戶端 JavaScript 使用。

舉例來說,Google Analytics 會使用 Urchin 流量監視器 (UTM) 參數評估廣告活動,但通常不會導致伺服器傳送不同的網頁。這表示 page1.html?utm_content=123page1.html?utm_content=456 會從伺服器提供相同網頁,因此可重複使用快取中的相同網頁。

同樣地,應用程式可能會使用其他僅在用戶端處理的網址參數。

No-Vary-Search 提案可讓伺服器指定不會導致所傳送資源有所差異的參數,因此瀏覽器可以重複使用先前快取的文件版本,這些版本只會因這些參數而有所不同。Chrome (和以 Chromium 為基礎的瀏覽器) 支援預先擷取和預先算繪的導覽推測。

推測規則支援使用 expects_no_vary_search,指出預期傳回 No-Vary-Search HTTP 標頭的位置。這樣一來,就能避免在看到回覆前下載不必要的檔案。

<script type="speculationrules">
{
  "prefetch": [{
    "urls": ["/products"],
    "expects_no_vary_search": "params=(\"id\")"
  }]
}
</script>

<a href="/https/developer.chrome.com/products?id=123">Product 123</a>
<a href="/https/developer.chrome.com/products?id=124">Product 124</a>

在本範例中,產品 ID 123124/products初始網頁 HTML 相同。不過,網頁內容最終會有所不同,因為系統會使用 JavaScript 透過 id 搜尋參數擷取產品資料,並在用戶端進行算繪。因此我們會預先擷取該網址,且該網址應會傳回 No-Vary-Search HTTP 標頭,顯示該網頁可用於任何 id 搜尋參數。

不過,如果使用者在預先擷取完成前點按任何連結,瀏覽器可能不會收到 /products 網頁。在這種情況下,瀏覽器不知道是否會包含 No-Vary-Search HTTP 標頭。瀏覽器接著會選擇是否要再次擷取連結,或是等待預先擷取作業完成,看看是否包含 No-Vary-Search HTTP 標頭。expects_no_vary_search 設定可讓瀏覽器瞭解網頁回應應包含 No-Vary-Search HTTP 標頭,並等待預先擷取完成。

您也可以在 expects_no_vary_search 中新增多個參數,並以空格分隔 (因為 No-Vary-Search 是 HTTP 結構化標頭):

    "expects_no_vary_search": "params=(\"param1\" \"param2\" \"param3\")"

推測規則限制和未來強化功能

推測規則僅限於在同一個分頁中開啟的網頁,但我們正努力減少這項限制

根據預設,推測僅限於同源網頁。推測相同網站的跨來源網頁 (例如 https://a.example.com 可能會預先算繪 https://b.example.com 上的網頁)。如要使用這項功能,推測的網頁 (本例中的 https://b.example.com) 必須加入 Supports-Loading-Mode: credentialed-prerender HTTP 標頭,否則 Chrome 會取消推測。

只要預先轉譯的網頁沒有 Cookie,且預先轉譯的網頁透過類似的 Supports-Loading-Mode: uncredentialed-prerender HTTP 標頭選擇加入,未來版本也可能允許預先轉譯非同網站的跨來源網頁

推測規則已支援跨來源預先擷取,但同樣僅限於不存在跨來源網域 Cookie 的情況。如果使用者先前造訪過該網站,且網站有 Cookie,系統就不會使用推測功能,且會在開發人員工具中顯示失敗。

考量到目前的限制,如果可以,建議您預先算繪同源網址,並嘗試預先擷取跨源網址,藉此改善內部連結和外部連結的使用者體驗:

<script type="speculationrules">
  {
    "prerender": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "moderate"
      }
    ],
    "prefetch": [
      {
        "where": { "not": { "href_matches": "/*" } },
        "eagerness": "moderate"
      }
    ]
  }
</script>

為確保安全,系統預設會限制跨來源連結的跨來源推測。對於跨來源目的地,這項功能比 <link rel="prefetch"> 更優異,因為這項功能不會傳送 Cookie,但仍會嘗試預先擷取,這會導致預先擷取作業浪費資源,需要重新傳送,或更糟的是,載入的網頁不正確。

偵測 Speculation Rules API 支援

您可以使用標準 HTML 檢查,偵測 Speculation Rules API 支援功能:

if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
  console.log('Your browser supports the Speculation Rules API.');
}

透過 JavaScript 動態新增推測規則

以下範例說明如何使用 JavaScript 新增 prerender 推測規則:

if (HTMLScriptElement.supports &&
    HTMLScriptElement.supports('speculationrules')) {
  const specScript = document.createElement('script');
  specScript.type = 'speculationrules';
  specRules = {
    prerender: [
      {
        urls: ['/next.html'],
      },
    ],
  };
  specScript.textContent = JSON.stringify(specRules);
  console.log('added speculation rules to: next.html');
  document.body.append(specScript);
}

如要查看使用 JavaScript 插入的 Speculation Rules API 預先算繪功能示範,請前往預先算繪示範頁面

使用 innerHTML<script type = "speculationrules"> 元素直接插入 DOM 時,系統不會註冊推測規則以確保安全性,因此必須如先前所示新增。不過,如果使用 innerHTML 動態插入含有新連結的內容,網頁上的現有規則就會偵測到這些連結。

同樣地,直接在 Chrome 開發人員工具中編輯「元素」面板來新增 <script type = "speculationrules"> 元素,並不會註冊推測規則,而是必須從「控制台」執行動態新增至 DOM 的指令碼,才能插入規則。

透過代碼管理工具新增推測規則

如要使用 Google 代碼管理工具 (GTM) 等代碼管理工具新增推測規則,必須透過 JavaScript 插入這些規則,而不是直接透過 GTM 新增 <script type = "speculationrules"> 元素,原因與先前所述相同:

Google 代碼管理工具中的自訂 HTML 代碼設定
透過 Google 代碼管理工具新增推測規則。

請注意,這個範例使用 var,因為 Google 代碼管理工具不支援 const

取消推測規則

移除推測規則會導致預先算繪作業取消。不過,在發生這種情況時,資源可能已用於啟動預先算繪,因此如果可能需要取消預先算繪,建議不要預先算繪。另一方面,快取資源仍可重複使用,因此取消作業不一定會完全浪費,或許仍有助於日後的推測和導覽。

Browser Support

  • Chrome: 138.
  • Edge: 138.
  • Firefox: not supported.
  • Safari: not supported.

Source

您也可以使用 Clear-Site-Data HTTP 標頭搭配 prefetchCacheprerenderCache 指令取消推測。

當伺服器上的狀態變更時,這項功能就非常實用。例如呼叫「加入購物車」API,或是登入或登出 API 時。

理想情況下,這些狀態更新會使用 Broadcast Channel API 等 API 傳播至預先算繪的網頁,但如果無法這麼做,或是在實作這類邏輯之前,取消推測會比較容易。

推測規則和內容安全政策

由於推測規則使用 <script> 元素,即使只包含 JSON,如果網站使用 script-src Content-Security-Policy,也必須納入推測規則 (使用雜湊或隨機數)。

現在可以將新的 inline-speculation-rules 新增至 script-src,支援從雜湊或非隨機數指令碼插入的 <script type="speculationrules"> 元素。這項功能不支援初始 HTML 中包含的規則,因此對於使用嚴格 CSP 的網站,必須透過 JavaScript 插入規則。

偵測並停用預先算繪

預先算繪通常能為使用者帶來正面的體驗,因為這樣網頁就能快速 (通常是即時) 算繪。預先算繪網頁可提供更優質的使用者體驗,這對使用者和網站擁有者都有好處。

不過,有時您不希望預先算繪網頁,例如網頁狀態會根據初始要求或網頁上執行的 JavaScript 變更時。

在 Chrome 中啟用及停用預先算繪功能

只有在 chrome://settings/performance/ 中啟用「預先載入網頁」設定的 Chrome 使用者,才能使用預先算繪功能。此外,如果裝置記憶體不足,或是作業系統處於「節省數據」或「節能」模式,預先算繪功能也會停用。請參閱「Chrome 限制」一節。

偵測並停用伺服器端預先算繪

預先算繪的網頁會隨附 Sec-Purpose HTTP 標頭:

Sec-Purpose: prefetch;prerender

使用 Speculation Rules API 預先擷取的網頁,這個標頭只會設為 prefetch

Sec-Purpose: prefetch

伺服器可以根據這個標頭回應,記錄推測要求、傳回不同內容,或防止預先算繪。如果傳回的最終回應代碼不是成功代碼 (也就是說,在重新導向後不在 200 到 299 的範圍內),系統就不會預先算繪網頁,並捨棄任何預先擷取的網頁。另請注意,204 和 205 回應不適用於預先算繪,但適用於預先擷取。

如果不希望預先算繪特定網頁,請傳回非 2XX 的回應代碼 (例如 503),確保系統不會預先算繪該網頁。不過,為提供最佳體驗,建議您改為允許預先算繪,但使用 JavaScript 延遲任何只應在實際瀏覽網頁時執行的動作。

在 JavaScript 中偵測預先算繪

網頁預先算繪時,document.prerendering API 會傳回 true。網頁可以使用這項功能,在預先算繪期間防止或延遲特定活動,直到網頁實際啟動為止。

預先算繪的文件啟動後,PerformanceNavigationTimingactivationStart 也會設為非零時間,代表預先算繪開始到文件實際啟動之間的時間。

您可以透過函式檢查預先算繪預先算繪的網頁,如下所示:

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

如要查看網頁是否已預先算繪 (完整或部分),最簡單的方法是在網頁啟動後開啟開發人員工具,並在控制台中輸入 performance.getEntriesByType('navigation')[0].activationStart。如果傳回非零值,表示網頁已預先算繪:

Chrome 開發人員工具的控制台顯示正數的 activationStart,表示網頁已預先算繪
在控制台中測試預先算繪。

使用者瀏覽網頁時,系統會啟用網頁,並在 document 上傳送 prerenderingchange 事件,您可使用這個事件啟用活動。這些活動原本會在網頁載入時預設啟動,但您想延遲到使用者實際瀏覽網頁時再啟動。

前端 JavaScript 可使用這些 API 偵測預先算繪的網頁,並採取適當行動。

對數據分析的影響

分析工具可用於評估網站使用情況,例如使用 Google Analytics 評估網頁瀏覽和事件。或是使用真人使用者監控 (RUM) 評估網頁的效能指標。

只有在使用者很可能會載入網頁時,才應預先算繪網頁。因此,只有在這種高機率的情況下 (超過 80% 的時間),Chrome 網址列才會預先算繪選項。

不過,特別是使用 Speculation Rules API 時,預先算繪的網頁可能會影響 Analytics,網站擁有者可能需要新增額外程式碼,才能在啟用時只針對預先算繪的網頁啟用 Analytics,因為並非所有 Analytics 供應商都會預設這麼做。

如要達成這個目標,可以使用 Promise,在文件預先算繪時等待 prerenderingchange 事件,或立即解決問題 (如果現在是這樣):

// Set up a promise for when the page is activated,
// which is needed for prerendered pages.
const whenActivated = new Promise((resolve) => {
  if (document.prerendering) {
    document.addEventListener('prerenderingchange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenActivated;
  // Initialise your analytics
}

initAnalytics();

另一種做法是延遲分析活動,直到網頁首次顯示為止,這樣就能涵蓋預先算繪的情況,以及在背景開啟分頁的情況 (例如按一下滑鼠右鍵並選取「在新分頁中開啟」):

// Set up a promise for when the page is first made visible
const whenFirstVisible = new Promise((resolve) => {
  if (document.hidden) {
    document.addEventListener('visibilitychange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenFirstVisible;
  // Initialise your analytics
}

initAnalytics();

這對分析和類似用途來說可能很合理,但在其他情況下,您可能希望為這些情況載入更多內容,因此可能想使用 document.prerenderingprerenderingchange 專門指定預先算繪的網頁。

在預先算繪期間保留其他內容

您可以使用先前討論的相同 API,在預先算繪階段保留其他內容。這可能是您不想在預先算繪階段執行的特定 JavaScript 部分,或整個指令碼元素。

舉例來說,如果指令碼如下:

<script src="https://example.com/app/script.js" async></script>

您可以將此項目變更為動態插入的指令碼元素,該元素只會根據先前的 whenActivated 函式插入:

async function addScript(scriptUrl) {
  await whenActivated;
  const script = document.createElement('script');
  script.src = 'scriptUrl';
  document.body.appendChild(script);
}

addScript('https://example.com/app/script.js');

這項功能可延遲載入包含 Analytics 的不同指令碼,或根據造訪期間可能變更的狀態或其他變數,轉譯內容。舉例來說,系統可能會暫緩顯示建議、登入狀態或購物車圖示,確保顯示最新資訊。

雖然使用預先算繪功能時,這種情況可能更常發生,但先前提到在背景分頁中載入的網頁也適用這些條件 (因此可以使用 whenFirstVisible 函式取代 whenActivated)。

在許多情況下,理想上應一併檢查一般 visibilitychange 變更的狀態,例如返回已在背景執行的頁面時,應使用購物車中的最新商品數量更新購物車計數器。因此,這並非預先算繪專屬問題,而是預先算繪只是讓現有問題更加明顯。

Chrome 會延遲載入特定 API,且不會轉譯第三方 iframe,因此您只需要手動延遲載入頂端的內容,即可減少手動包裝指令碼或函式的需求。

衡量成效

如要評估成效指標,Analytics 應考量是否最好根據啟用時間 (而非瀏覽器 API 回報的網頁載入時間) 評估這些指標。

網站使用體驗核心指標是 Chrome 透過 Chrome 使用者體驗報告測量,旨在評估使用者體驗。因此,這些指標的計算依據是啟用時間。舉例來說,這通常會導致 LCP 為 0 秒,顯示這是改善網站體驗核心指標的好方法。

從 3.1.0 版開始,web-vitals 程式庫已更新,可處理預先算繪的導覽,方式與 Chrome 評估核心網頁指標相同。如果網頁已完整或部分預先算繪,這個版本也會在 Metric.navigationType 屬性中,為這些指標標記預先算繪的導覽。

評估預先算繪

如要查看網頁是否經過預先算繪,請查看 PerformanceNavigationTiming 的非零 activationStart 項目。然後,您可以使用自訂維度記錄這項資訊,或在記錄網頁瀏覽時使用類似方法,例如使用先前所述的 pagePrerendered 函式

// Set Custom Dimension for Prerender status
gtag('set', { 'dimension1': pagePrerendered() });
// Initialise GA - including sending page view by default
gtag('config', 'G-12345678-1');

這樣一來,數據分析就能顯示預先算繪的導覽次數與其他導覽類型相比的結果,您也能將任何成效指標或業務指標與這些不同的導覽類型建立關聯。網頁載入速度越快,使用者越開心,這通常會對業務指標產生實際影響,我們的案例研究就是證明。

評估預先算繪網頁對業務的影響後,您可以決定是否要投入更多心力使用這項技術,允許預先算繪更多瀏覽活動,或是調查網頁未預先算繪的原因。

評估命中率

除了評估預先算繪後造訪的網頁所帶來的影響,也請務必評估預先算繪但後續造訪的網頁。這可能表示您預先算繪的內容過多,導致使用者耗用寶貴的資源,但效益不大。

如要測量這項指標,請在插入推測規則時觸發數據分析事件 (先使用 HTMLScriptElement.supports('speculationrules') 檢查瀏覽器是否支援預先算繪),指出已要求預先算繪。(請注意,即使系統要求預先算繪,也不代表預先算繪已開始或完成,因為如先前所述,預先算繪只是瀏覽器的提示,瀏覽器可能會根據使用者設定、目前的記憶體用量或其他啟發式方法,選擇不預先算繪網頁)。

然後,您可以比較這些事件的數量與實際預先算繪的網頁瀏覽次數。或者,如果這樣比較容易比較,也可以在啟用時觸發另一個事件。

然後查看這兩個數字的差異,即可估算「成功命中率」。如果網頁使用 Speculation Rules API 預先算繪網頁,您可以適當調整規則,確保命中率維持在高點,在耗用使用者資源協助他們與不必要耗用之間取得平衡。

請注意,由於網址列預先算繪,可能會有部分預先算繪作業正在進行,而不只是您的推測規則。如要區分這些項目,可以檢查 document.referrer (網址列導覽會空白,包括預先算繪的網址列導覽)。

請記得查看沒有預先算繪的網頁,因為這可能表示這些網頁不符合預先算繪的資格,即使是從網址列也是如此。這表示您可能無法從這項效能提升功能獲益。Chrome 團隊打算新增額外工具,測試預先算繪資格,可能類似於 bfcache 測試工具,也可能新增 API,說明預先算繪失敗的原因。

對擴充功能的影響

請參閱「Chrome 擴充功能:擴充 API 以支援即時瀏覽」這篇專文,瞭解擴充功能作者可能需要考慮的預先算繪網頁相關事項。

意見回饋

Chrome 團隊正積極開發預先算繪功能,並計畫擴大 Chrome 108 版本提供的功能範圍。歡迎透過 GitHub 存放區問題追蹤器提供意見回饋,也期待聽到並分享這個令人振奮的新 API 案例研究。

特別銘謝

縮圖圖片來源:Marc-Olivier Jodoin 發表於 Unsplash