如何評估及最佳化簽署交換,以便充分發揮其效益
簽署交換 (SXG) 是一種改善網頁速度的方式,主要針對最大內容繪製 (LCP)。參照網站 (目前為 Google 搜尋) 連結至網頁時,可以先在使用者點選連結前,將該網頁預先擷取至瀏覽器快取。
您可以建立網頁,在預先擷取時,在轉譯網頁的關鍵路徑上不需要網路連線!在 4G 連線下,這個網頁的載入時間從 2.8 秒縮短為 0.9 秒 (剩餘的 0.9 秒主要是 CPU 使用時間):
目前大多數發布 SXG 的使用者都會使用 Cloudflare 的 自動簽署交換機制 (ASX) 功能 (但也有開放原始碼選項):
在許多情況下,只要勾選核取方塊啟用這項功能,就能獲得上述大幅改善的效果。有時,您可能需要執行其他幾個步驟,確保這些 SXG 在管道各個階段都能正常運作,並充分發揮預先載入的優勢。
在 Cloudflare 推出後的幾個月內,我一直在各種 論壇上閱讀並回覆問題,並學習如何建議網站如何確保充分運用 SXG 部署。這篇文章收錄了我的建議。我會逐步說明以下步驟:
- 使用 WebPageTest 分析 SXG 效能。
- 如果「分析」步驟顯示 SXG 管線無法運作,請對 SXG 管線進行偵錯。
- 為 SXG 預先載入最佳化網頁,包括設定最佳
max-age
和預先載入會阻斷轉譯的子資源。 - 選取適當的實驗和控制組,使用 Google Analytics 評估 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 擴充功能造訪網頁,然後按一下擴充功能圖示,查看快取網址:
完成這些測試後,請前往「測試記錄」,選取兩項測試,然後按一下「比較」:
將 &medianMetric=LCP
附加至比較網址,讓 WebPageTest 選取比較結果兩邊的 LCP 中位數。(預設為 Speed Index 中位數)。
如要比較瀑布圖,請展開「瀑布圖不透明度」部分,然後拖曳滑桿。如要查看影片,請按一下「調整膠卷設定」,然後在對話方塊中向下捲動,並按一下「查看影片」。
如果 SXG 預先載入成功,您會發現「with SXG」資料表中沒有 HTML 資料列,且子資源的擷取作業會提早開始。例如比較「Before」和「After」:
偵錯
如果 WebPageTest 顯示 SXG 正在預先載入,表示管道中的所有步驟都已成功完成;您可以略過「最佳化」一節,瞭解如何進一步改善 LCP。否則,您必須找出管道中失敗的位置和原因。請繼續閱讀,瞭解如何進行。
發布中
請確認網頁是以 SXG 格式產生。為此,您需要假裝成檢索器。最簡單的方法是使用 SXG Validator Chrome 擴充功能:
擴充功能會使用 Accept
要求標頭擷取目前的網址,並指出偏好 SXG 版本。如果「Origin」旁邊顯示勾號 (✅),表示系統已傳回 SXG;你可以略過「索引」部分。
如果畫面上顯示叉號 (❌),表示系統未傳回 SXG:
如果啟用了 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 -verify -uri $URL
如果 SXG 存在且有效,您會看到 SXG 的易讀列印內容。否則系統會顯示錯誤訊息。
建立索引
請確認 Google 搜尋已成功編入索引你的 SXG。開啟 Chrome 開發人員工具,然後在 Google 搜尋中搜尋您的網頁。如果已將其索引為 SXG,Google 連結至您網頁的連結就會包含 data-sxg-url
,指向 webpkgcache.com 的副本:
如果 Google 搜尋認為使用者可能會點選某個結果,也會預先擷取該結果:
<link>
元素會指示瀏覽器將 SXG 下載至預先擷取快取。使用者點選 <a>
元素時,瀏覽器會使用快取的 SXG 轉譯網頁。
您也可以前往開發人員工具的「網路」分頁,搜尋含有 webpkgcache
的網址,藉此查看預先載入的證據。
如果 <a>
指向 webpkgcache.com,表示已簽署的交換機制已在 Google 搜尋中建立索引。您可以直接跳到「擷取」部分。
否則,可能是 Google 尚未重新檢索網頁,因為你已啟用 SXG。試試 Google Search Console 網址檢查工具:
如果有 digest: mi-sha256-03=...
標頭,表示 Google 已成功檢索 SXG 版本。
如果沒有 digest
標頭,可能表示系統並未將 SXG 提供給 Googlebot,或是自啟用 SXG 以來,索引並未更新。
如果系統成功檢索 SXG,但仍未連結至該檔案,則可能是未符合 SXG 快取規定。下一節會說明這些內容。
擷取
Google 搜尋在為 SXG 建立索引時,會將副本傳送至 Google SXG 快取,並根據快取規定驗證副本。Chrome 擴充功能會顯示結果:
如果不符合規定,您會看到一個叉號 (❌) 和警告訊息,說明原因:
在這種情況下,網頁會像啟用 SXG 前一樣運作。Google 會連結至原始主機上的網頁,但不會預先擷取 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 預先載入功能的中位數結果。點選下方的「之後」:
我發現預先載入功能運作正常。系統會從關鍵路徑中移除 HTML,因此所有子資源都能提早載入。不過,LCP (綠色虛線) 從 2 秒增加到 2.1 秒。
為了診斷這個問題,我查看了電影膠片。我發現網頁在 SXG 中呈現的結果不同。在純 HTML 中,Chrome 判斷 LCP 的「最大元素」是標題。不過,在 SXG 版本中,頁面新增了延遲載入的橫幅,導致標題被推到折疊下方,並使新的最大元素成為延遲載入的 Cookie 同意聲明對話方塊。所有項目的算繪速度都比之前快,但版面配置變更導致指標回報的速度變慢。
經過深入調查,我發現版面配置差異的原因是網頁會因 User-Agent
而異動,且邏輯中出現錯誤。雖然 SXG 檢索標頭指出行動裝置,但系統仍會提供電腦版網頁。修正後,瀏覽器再次正確將網頁標題視為最大元素。
點選「After」後,我發現預先擷取的 LCP 降至 1.3 秒:
所有板型規格都已啟用 SXG。為因應這種情況,請確認符合下列其中一項條件:
- 您的網頁並未由
User-Agent
Vary
(例如,使用回應式設計或不同的行動版/電腦版網址)。 - 如果網頁使用動態服務,則會使用
<meta name=supported-media content=...>
加註為行動裝置或電腦專用。
子資源
您可以使用 SXG 預先載入子資源 (包括圖片) 和 HTML。Cloudflare ASX 會掃描 HTML 中的同源 (第一方) <link rel=preload>
元素,並將其轉換為 SXG 相容的 Link 標頭。詳情請參閱原始碼,請見這裡和這裡。
如果運作正常,您會在 Google 搜尋中看到其他預先載入內容:
如要針對 LCP 進行最佳化,請仔細查看時間軸,找出在轉譯最大元素時,哪些資源位於關鍵路徑上。如果無法預先擷取,請考慮是否可以將其移出重要路徑。請留意是否有指令碼會在載入完成前隱藏網頁。
Google SXG 快取可預先載入最多 20 個子資源,而 ASX 會確保不會超過這個限制。不過,新增太多子資源預先載入內容可能會帶來風險。瀏覽器只會在所有子資源都已完成擷取時使用預先載入的子資源,以防止跨網站追蹤。子資源越多,在使用者點按前往網頁前,子資源完成預先載入的機率就越低。
SXG Validator 目前不會檢查子資源;如要進行偵錯,請同時使用 curl
或 dump-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」,另一個命名為「參照來源」。(內建的「來源」維度具有工作階段範圍,因此不會排除同一網站的導覽)。
建立名為「SXG 對照組」的自訂區隔,並將下列篩選器以 AND 運算結合:
referrer
開頭是https://www.google.
Browser
與Chrome
完全相符Browser
版本與規則運算式^(9[8-9]|[0-9]{3})
相符isSXG
與false
完全相符
建立這個區隔的副本,並命名為「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 對照組」和「SXG」。
按一下「提交」,您應該會看到兩個區隔的 LCP 分布情形。這應該會填入「第 75 百分位數的 LCP 改善幅度為 Y 毫秒」的 Y 值:
注意事項
套用上述所有篩選器後,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 搜尋說明文件。