使用 Signed Exchange 最佳化 LCP

如何評估及最佳化簽署交換,以便充分發揮其效益

Devin Mullins
Devin Mullins

簽署交換 (SXG) 是一種改善網頁速度的方式,主要針對最大內容繪製 (LCP)。參照網站 (目前為 Google 搜尋) 連結至網頁時,可以先在使用者點選連結前,將該網頁預先擷取至瀏覽器快取。

您可以建立網頁,在預先擷取時,在轉譯網頁的關鍵路徑上不需要網路連線!在 4G 連線下,這個網頁的載入時間從 2.8 秒縮短為 0.9 秒 (剩餘的 0.9 秒主要是 CPU 使用時間):

目前大多數發布 SXG 的使用者都會使用 Cloudflare 的 自動簽署交換機制 (ASX) 功能 (但也有開放原始碼選項):

Cloudflare 設定面板,其中包含啟用自動簽署交換的核取方塊

在許多情況下,只要勾選核取方塊啟用這項功能,就能獲得上述大幅改善的效果。有時,您可能需要執行其他幾個步驟,確保這些 SXG 在管道各個階段都能正常運作,並充分發揮預先載入的優勢。

在 Cloudflare 推出後的幾個月內,我一直在各種 論壇上閱讀並回覆問題,並學習如何建議網站如何確保充分運用 SXG 部署。這篇文章收錄了我的建議。我會逐步說明以下步驟:

簡介

SXG 檔案包含網址、一組 HTTP 回應標頭和回應主體,所有內容都經過 Web PKI 憑證的加密簽署。瀏覽器載入 SXG 時,會驗證下列所有項目:

  • SXG 並未過期。
  • 簽章與網址、標頭、主體和憑證相符。
  • 憑證有效且與網址相符。

如果驗證失敗,瀏覽器會放棄 SXG,改為擷取已簽署的網址。如果驗證成功,瀏覽器會載入已簽署的回應,並將其視為直接來自已簽署網址。只要未過期或經過修改,即可在任何伺服器上重新代管 SXG。

以 Google 搜尋來說,SXG 可啟用搜尋結果中的網頁預先擷取功能。如果網頁支援 SXG,Google 搜尋可預先擷取網頁的快取副本,並代管在 webpkgcache.com 上。這些 webpkgcache.com 網址不會影響網頁的顯示或行為,因為瀏覽器會遵循原始的已簽署網址。預先載入可讓網頁載入速度大幅提升。

分析

如要瞭解 SXG 的優點,請先使用實驗室工具,在可重現的情況下分析 SXG 效能。您可以使用 WebPageTest 比較有無使用 SXG 預先載入功能的瀑布圖和 LCP。

如要產生不含 SXG 的測試,請按照下列步驟操作:

  • 前往 WebPageTest 並登入。登入後,系統會儲存測試記錄,方便您日後進行比較。
  • 輸入要測試的網址。
  • 前往「進階設定」。(您需要使用進階設定進行 SXG 測試,因此在這裡使用這項功能有助於確保測試選項相同)。
  • 在「測試設定」分頁中,建議將「連線」設為 4G,並將「要執行的測試次數」增加至 7 次。
  • 按一下「開始測試」

請按照上述步驟使用 SXG 產生測試,但在點選「Start Test」之前,請前往「Script」分頁,貼上以下 WebPageTest 指令碼,並依指示修改兩個 navigate 網址:

// Disable log collection for the first step. We only want the waterfall for the target navigation.
logData 0

// Visit a search result page that includes your page.
navigate https://google.com/search?q=site%3Asigned-exchange-testing.dev+image

// Wait for the prefetch to succeed.
sleep 10

// Re-enable log collection.
logData 1

// Navigate to the prefetched SXG on the Google SXG Cache.
navigate https://signed--exchange--testing-dev.webpkgcache.com/doc/-/s/signed-exchange-testing.dev/sxgs/valid-image-subresource.html

針對第一個 navigate 網址,如果您的網頁尚未顯示在任何 Google 搜尋結果中,您可以使用這個預先載入網頁產生假搜尋結果網頁。

如要判斷第二個 navigate 網址,請使用 SXG Validator Chrome 擴充功能造訪網頁,然後按一下擴充功能圖示,查看快取網址:

SXG Validator 顯示快取資訊,包括網址

完成這些測試後,請前往「測試記錄」,選取兩項測試,然後按一下「比較」

測試記錄,其中兩項測試已勾選,並醒目顯示「比較」按鈕

&medianMetric=LCP 附加至比較網址,讓 WebPageTest 選取比較結果兩邊的 LCP 中位數。(預設為 Speed Index 中位數)。

如要比較瀑布圖,請展開「瀑布圖不透明度」部分,然後拖曳滑桿。如要查看影片,請按一下「調整膠卷設定」,然後在對話方塊中向下捲動,並按一下「查看影片」

如果 SXG 預先載入成功,您會發現「with SXG」資料表中沒有 HTML 資料列,且子資源的擷取作業會提早開始。例如比較「Before」和「After」:

沒有 SXG 預先載入的網路水道;第一列是 HTML 擷取,需要 1050 毫秒 網路水道搭配 SXG 預先載入功能;HTML 已預先載入,可讓所有子資源提早 1050 毫秒開始載入

偵錯

如果 WebPageTest 顯示 SXG 正在預先載入,表示管道中的所有步驟都已成功完成;您可以略過「最佳化」一節,瞭解如何進一步改善 LCP。否則,您必須找出管道中失敗的位置和原因。請繼續閱讀,瞭解如何進行。

發布中

請確認網頁是以 SXG 格式產生。為此,您需要假裝成檢索器。最簡單的方法是使用 SXG Validator Chrome 擴充功能

SXG 驗證工具顯示勾號 (✅) 和內容類型 application/signed-exchange;v=b3

擴充功能會使用 Accept 要求標頭擷取目前的網址,並指出偏好 SXG 版本。如果「Origin」旁邊顯示勾號 (✅),表示系統已傳回 SXG;你可以略過「索引」部分。

如果畫面上顯示叉號 (❌),表示系統未傳回 SXG:

SXG 驗證工具顯示交叉標記 (❌) 和內容類型 text/html

如果啟用了 Cloudflare ASX,出現 X 號 (❌) 的可能性最高的原因,是因為快取控制回應標頭阻止了快取。ASX 會查看下列名稱的標頭:

  • Cache-Control
  • CDN-Cache-Control
  • Surrogate-Control
  • Cloudflare-CDN-Cache-Control

如果任何標頭包含下列任何標頭值,系統就不會產生 SXG:

  • private
  • no-store
  • no-cache
  • max-age 小於 120,除非由大於或等於 120 的 s-maxage 覆寫

在這種情況下,ASX 不會建立 SXG,因為 SXG 可能會快取並重複使用,用於多個造訪和多位訪客。

這些有狀態回應標頭 (Set-Cookie除外) 也是導致出現 X 號 (❌) 的另一個可能原因。ASX 會移除 Set-Cookie 標頭,以符合 SXG 規格。

另一個可能的原因是存在 Vary: Cookie 回應標頭。Googlebot 會擷取 SXG,但不會使用使用者憑證,且可能會將這些內容提供給多位訪客。如果您根據使用者的 Cookie 為他們提供不同的 HTML,他們可能會看到錯誤的體驗,例如登出畫面。

除了 Chrome 擴充功能外,您也可以使用 curl 等工具:

curl -siH "Accept: application/signed-exchange;v=b3" $URL | less

dump-signedexchange

dump-signedexchange -verify -uri $URL

如果 SXG 存在且有效,您會看到 SXG 的易讀列印內容。否則系統會顯示錯誤訊息。

建立索引

請確認 Google 搜尋已成功編入索引你的 SXG。開啟 Chrome 開發人員工具,然後在 Google 搜尋中搜尋您的網頁。如果已將其索引為 SXG,Google 連結至您網頁的連結就會包含 data-sxg-url,指向 webpkgcache.com 的副本:

Google 搜尋結果,開發人員工具顯示指向 webpkgcache.com 的錨點標記

如果 Google 搜尋認為使用者可能會點選某個結果,也會預先擷取該結果:

Google 搜尋結果,開發人員工具顯示 webpkgcache.com 的 rel=prefetch 連結

<link> 元素會指示瀏覽器將 SXG 下載至預先擷取快取。使用者點選 <a> 元素時,瀏覽器會使用快取的 SXG 轉譯網頁。

您也可以前往開發人員工具的「網路」分頁,搜尋含有 webpkgcache 的網址,藉此查看預先載入的證據。

如果 <a> 指向 webpkgcache.com,表示已簽署的交換機制已在 Google 搜尋中建立索引。您可以直接跳到「擷取」部分。

否則,可能是 Google 尚未重新檢索網頁,因為你已啟用 SXG。試試 Google Search Console 網址檢查工具

使用 Search Console 網址檢查工具,按一下「查看已檢索的網頁」,然後點選「更多資訊」

如果有 digest: mi-sha256-03=... 標頭,表示 Google 已成功檢索 SXG 版本。

如果沒有 digest 標頭,可能表示系統並未將 SXG 提供給 Googlebot,或是自啟用 SXG 以來,索引並未更新。

如果系統成功檢索 SXG,但仍未連結至該檔案,則可能是未符合 SXG 快取規定。下一節會說明這些內容。

擷取

Google 搜尋在為 SXG 建立索引時,會將副本傳送至 Google SXG 快取,並根據快取規定驗證副本。Chrome 擴充功能會顯示結果:

SXG 驗證工具顯示勾號 (✅) 且沒有警告訊息

如果畫面顯示勾號 (✅),您可以直接跳到「最佳化」

如果不符合規定,您會看到一個叉號 (❌) 和警告訊息,說明原因:

SXG 驗證工具顯示交叉標記 (❌) 和警告訊息,指出

在這種情況下,網頁會像啟用 SXG 前一樣運作。Google 會連結至原始主機上的網頁,但不會預先擷取 SXG。

如果快取的副本已過期,且系統正在背景重新擷取,您會看到沙漏圖示 (⌛):

SXG 驗證工具顯示的沙漏圖示 (⌛) 和沒有警告訊息

SXG 的 Google 開發人員說明文件也提供手動查詢快取的操作說明。

最佳化

如果 SXG Validator Chrome 擴充功能顯示所有勾號 (✅),表示您已完成 SXG,可以提供給使用者!請繼續閱讀,瞭解如何最佳化網頁,以便充分運用 SXG 改善 LCP。

max-age

SXG 到期後,Google SXG 快取會在背景擷取新的副本。在等待該擷取作業期間,系統會將使用者導向原始主機上的網頁,但該網頁並未預先擷取。設定的 Cache-Control: max-age 時間越長,背景擷取的發生頻率就越低,因此預先擷取功能可減少的 LCP 次數就越多。

這是效能和新鮮度之間的取捨,快取可讓網站擁有者為 SXG 提供 2 分鐘至 7 天的最大年齡,以符合每個網頁的特定需求。我們發現以下情況:

  • max-age=86400 (1 天) 或更長的時間,可有效提升成效
  • max-age=120 (2 分鐘) 不會

我們希望在進一步研究資料後,能進一步瞭解這兩者之間的值。

user-agent

有一次,我發現使用預先載入的 SXG 時,LCP 增加了。我執行了 WebPageTest,比較未使用和已使用 SXG 預先載入功能的中位數結果。點選下方的「之後」

未使用 SXG 預先載入的網路階層;LCP 為 2 秒 網路階層搭配 SXG 預先載入功能;HTML 已預先載入,可讓所有子資源提早 800 毫秒開始載入,但 LCP 為 2.1 秒

我發現預先載入功能運作正常。系統會從關鍵路徑中移除 HTML,因此所有子資源都能提早載入。不過,LCP (綠色虛線) 從 2 秒增加到 2.1 秒

為了診斷這個問題,我查看了電影膠片。我發現網頁在 SXG 中呈現的結果不同。在純 HTML 中,Chrome 判斷 LCP 的「最大元素」是標題。不過,在 SXG 版本中,頁面新增了延遲載入的橫幅,導致標題被推到折疊下方,並使新的最大元素成為延遲載入的 Cookie 同意聲明對話方塊。所有項目的算繪速度都比之前快,但版面配置變更導致指標回報的速度變慢。

經過深入調查,我發現版面配置差異的原因是網頁會因 User-Agent 而異動,且邏輯中出現錯誤。雖然 SXG 檢索標頭指出行動裝置,但系統仍會提供電腦版網頁。修正後,瀏覽器再次正確將網頁標題視為最大元素。

點選「After」後,我發現預先擷取的 LCP 降至 1.3 秒

未使用 SXG 預先載入的網路階層;LCP 為 2 秒 網路瀑布流程 (含 SXG 預先擷取);LCP 為 1.3 秒

所有板型規格都已啟用 SXG。為因應這種情況,請確認符合下列其中一項條件:

子資源

您可以使用 SXG 預先載入子資源 (包括圖片) 和 HTML。Cloudflare ASX 會掃描 HTML 中的同源 (第一方) <link rel=preload> 元素,並將其轉換為 SXG 相容的 Link 標頭。詳情請參閱原始碼,請見這裡這裡

如果運作正常,您會在 Google 搜尋中看到其他預先載入內容:

Google 搜尋結果,顯示開發人員工具「網路」分頁中的 /sub/…/image.jpg 預先擷取內容

如要針對 LCP 進行最佳化,請仔細查看時間軸,找出在轉譯最大元素時,哪些資源位於關鍵路徑上。如果無法預先擷取,請考慮是否可以將其移出重要路徑。請留意是否有指令碼會在載入完成前隱藏網頁。

Google SXG 快取可預先載入最多 20 個子資源,而 ASX 會確保不會超過這個限制。不過,新增太多子資源預先載入內容可能會帶來風險。瀏覽器只會在所有子資源都已完成擷取時使用預先載入的子資源,以防止跨網站追蹤。子資源越多,在使用者點按前往網頁前,子資源完成預先載入的機率就越低。

SXG Validator 目前不會檢查子資源;如要進行偵錯,請同時使用 curldump-signedexchange

測量

在 WebPageTest 中完成 LCP 改善最佳化後,您可以評估 SXG 預先載入對網站整體效能帶來的影響。

伺服器端指標

評估伺服器端指標 (例如第 1 個位元組時間 (TTFB)) 時,請務必注意,您的網站只會向接受該格式的檢索器提供 SXG。請將 TTFB 的評估範圍限制在來自真人使用者的要求,而非機器人。您可能會發現,產生 SXG 會增加檢索器要求的 TTFB,但這不會影響訪客體驗。

用戶端指標

對用戶端指標 (尤其是 LCP) 而言,SXG 可帶來最大的速度效益。在評估成效時,您只需啟用 Cloudflare ASX,等待 Googlebot 重新檢索,再等待 28 天讓核心網頁體驗 (Core Web Vitals, CWV) 匯總,然後查看新的 CWV 數值即可。不過,如果在這個時間範圍內發生其他變化,就可能很難發現這項變化。

相反地,我發現針對可能受到影響的網頁載入作業「放大檢視」很有幫助,並將其定義為「SXG 會影響 X% 的網頁瀏覽量,在第 75 百分位數改善 LCP 達 Y 毫秒」。

目前,只有在特定情況下才會執行 SXG 預先載入:

  • Chromium 瀏覽器 (例如 Chrome 或 Edge,但不適用於 iOS),M98 以上版本
  • Referer: google.com 或其他 Google 搜尋網域。(請注意,在 Google Analytics 中,參照來源代碼會套用至工作階段中的所有網頁瀏覽次數,而 SXG 預先載入功能只會套用至從 Google 搜尋直接連結的第一個網頁瀏覽次數)。

請參閱當代研究專區,瞭解如何評估「X% 的網頁瀏覽量」和「將 LCP 縮短 Y 毫秒」。

當代研究

查看實際使用者監控 (RUM) 資料時,請將網頁載入作業分為 SXG 和非 SXG。進行這項操作時,請務必限制要查看的網頁載入組合,以便非 SXG 端符合 SXG 的資格條件,避免出現選取偏誤。否則,下列所有項目只會存在於非 SXG 網頁載入作業中,而這類作業可能會產生不同的 LCP:

  • iOS 裝置:由於使用者所使用的硬體或網路速度不同。
  • 舊版 Chromium 瀏覽器:原因相同。
  • 電腦裝置:同樣的原因,或是因為網頁版面配置導致系統選擇不同的「最大元素」。
  • 同網站導覽 (訪客在網站內點選連結):因為這類導覽可重複使用先前網頁載入時快取的子資源。

在 Google Analytics (通用 Analytics) 中,使用「命中」範圍建立兩個自訂維度,一個命名為「isSXG」,另一個命名為「參照來源」。(內建的「來源」維度具有工作階段範圍,因此不會排除同一網站的導覽)。

Google Analytics 維度編輯器,顯示建議設定

建立名為「SXG 對照組」的自訂區隔,並將下列篩選器以 AND 運算結合:

  • referrer開頭是 https://www.google.
  • BrowserChrome 完全相符
  • Browser 版本與規則運算式 ^(9[8-9]|[0-9]{3}) 相符
  • isSXGfalse 完全相符
Google Analytics 區隔編輯器,其中顯示建議的篩選器

建立這個區隔的副本,並命名為「SXG」,但 isSXG 必須與 true 完全相符。

在網站範本中,請在 Google Analytics 程式碼片段上方加入下列程式碼片段。這是 ASX 在產生 SXG 時會將 false 變更為 true特殊語法

<script data-issxg-var>window.isSXG=false</script>

按照建議自訂 Google Analytics 報表指令碼,以便記錄 LCP。如果您使用的是 gtag.js,請修改 'config' 指令來設定自訂維度 (將 'dimension1''dimension2' 替換為 Google Analytics 建議使用的名稱):

gtag('config', 'YOUR_TRACKING_ID', {
  'dimension1': String(isSXG),
  'dimension2': document.referrer,
});

如果您使用的是 analytics.js,請按照這裡的說明修改 'create' 指令。

等待幾天收集到一些資料後,請前往 Google Analytics 事件報表,為 SXG 區隔新增細查。這應該是「SXG 影響 X% 的網頁瀏覽量」中的 X:

含有 SXG 區隔的 Google Analytics 事件報表,顯示 12.5% 的不重複事件

最後,前往網頁重要指標報表,選取「選擇區隔」,然後選取「SXG 對照組」和「SXG」。

網站體驗報告,其中包含 SXG 對照組和 SXG 的選項

按一下「提交」,您應該會看到兩個區隔的 LCP 分布情形。這應該會填入「第 75 百分位數的 LCP 改善幅度為 Y 毫秒」的 Y 值:

網站體驗核心指標報表:顯示 SXG 對照組和 SXG 的 LCP 分布情形

注意事項

套用上述所有篩選器後,SXG 反事實網頁載入作業應包含以下項目:

  • 快取未命中:如果 Google SXG 快取中沒有特定網址的最新 SXG 副本,系統會重新導向至網站的原始網址。
  • 其他結果類型:Google 搜尋目前僅支援標準網頁結果和幾種其他類型的 SXG。其他內容 (例如精選摘要和焦點新聞輪轉介面) 則會連結至網站上的原始網址。
  • 不符合資格的網址:如果網站上的部分網頁不符合 SXG 資格 (例如無法快取),就可能會出現在這組中。

在 SXG 網頁載入作業與上述非 SXG 網頁載入作業之間,可能仍會存在偏差,但其幅度應低於「當代研究」一節開頭提到的偏差。舉例來說,非快取網頁的載入速度可能比快取網頁快或慢。如果您認為這可能是問題所在,不妨查看特定 SXG 適用網址的資料,看看結果是否與整體研究相符。

如果您的網站有部分 AMP 網頁,這些網頁可能已從 Google 搜尋中預先擷取,因此啟用 SXG 後,成效可能不會有所改善。建議您新增篩選器來排除這類網頁,進一步「放大」相關變更。

最後,即使解決所有選取偏差問題,仍有可能發生倖存者偏差,導致 LCP 改善成效在 RUM 統計資料中看起來像是惡化。這篇文章清楚說明瞭這種風險,並建議您查看某些形式的放棄指標,以偵測是否發生這種情況。

研究前/後

為證實當代研究的結果,建議您比較啟用 SXG 前後的 LCP。請不要只限於 SXG 網頁瀏覽次數,以免出現上述潛在偏差。請改為查看符合 SXG 資格的結果,也就是上述區隔定義,但不含 isSXG 限制。

請注意,Google 搜尋可能需要最多數週的時間,才能重新檢索網站上的所有網頁,以便識別已啟用 SXG 的網頁。在這些幾週內,可能會出現其他偏差:

  • 使用者硬體的全新瀏覽器版本或改善項目,可能會加快網頁載入速度。
  • 節慶等重大活動可能會造成流量異常。

您也可以查看整體 75 百分位 LCP 的變化情形,確認上述研究結果。瞭解母體的子集,不一定能代表整體母體。舉例來說,假設 SXG 可將 10% 的網頁載入時間縮短 800 毫秒。

  • 如果這些網頁載入時間已是前 10% 最快的網頁載入時間,則不會影響第 75 百分位。
  • 如果這些網頁載入時間是 10% 最慢的網頁載入時間,但比 75 百分位 LCP 慢了 800 毫秒以上,則不會影響 75 百分位。

這些是極端的例子,可能不符合現實情況,但希望能說明問題。實際上,SXG 可能會影響大多數網站的 75 百分位數。跨網站導覽通常是最慢的,因此預先載入功能帶來的改善效果通常也相當顯著。

取消訂閱部分網址

最後,您可以為網站上的部分網址停用 SXG,藉此比較 SXG 成效。舉例來說,您可以設定 CDN-Cache-Control: no-store 標頭,避免 Cloudflare ASX 產生 SXG。我不建議這麼做。

相較於其他研究方法,這類研究可能會產生更大的選樣偏差。舉例來說,如果您將網站首頁或類似的熱門網址選入控制組或實驗組,結果可能會大相逕庭。

預留研究

評估影響力的理想做法是進行保留研究。很抱歉,您目前無法執行這類測試。我們預計日後支援這類測試。

保留研究具有下列屬性:

  • 在實驗組中,部分隨機網頁瀏覽量「會」成為 SXG,但會「延後」,並改為以非 SXG 形式放送。這樣一來,您就能在相同的使用者、裝置、情境和網頁之間進行「同類比對」。
  • 這些未顯示的網頁瀏覽 (又稱為反事實) 會在數據分析中標示為「未顯示」。這可讓我們「放大」檢視資料,比較控制組的 SXG 網頁載入情形,以及實驗中的 SXG 對照組。這麼做可減少其他網頁載入作業的雜訊,這些作業不會受到 SXG 預先載入的影響。

這麼做可消除上述可能的選取偏差來源,但無法消除 LCP 倖存者偏差的風險。這兩項屬性都需要由瀏覽器或參照來源啟用。

結論

大功告成!講了這麼多,希望這篇文章能讓您更全面地瞭解如何在實驗室測試中測試 SXG 效能、如何透過密集的實驗室測試回饋迴圈來提升效能,以及如何評估實際效能。將這些元素結合起來,就能充分運用 SXG,並確保 SXG 能為你的網站和使用者帶來好處。

如果您有其他關於如何擷取 SXG 成效的建議,歡迎與我們聯絡!針對 developer.chrome.com 提交錯誤,並附上改善建議。

如要進一步瞭解已簽署的交換機制,請參閱 web.dev 說明文件Google 搜尋說明文件