最大化您的快取命中率

改善網店成效的最佳方式之一,就是最大化您的快取命中率。任何可以從 Managed Runtime 的 CDN 快取中完成的要求,都可以視為快取命中。每次快取命中都能讓您加快使用者的頁面載入速度,因為您節省了在伺服器端轉譯頁面、以及向後端系統和 API 發出要求的成本。

這份指南介紹了最大化快取命中率的三種不同技術:設定最佳快取存留期、條件式轉譯、篩選查詢字串。讓我們來仔細看看每種技術。

快取 HTTP 要求的最佳期間會根據要求內容而定。載入不常變更之內容頁面的要求可以穩定地快取很長一段時間。相反地,經常更新產品的產品清單頁面可能需要較短的快取存留期,例如 15 分鐘。可以的話,盡量選擇較長的快取存留期,以最大化快取命中率。

HTTP 回應中的 Cache-Control 標頭決定了對頁面要求的回應儲存在 CDN 快取中的時間長度。PWA Kit 專案中的頁面回應預設快取存留期為 600 秒 (10 分鐘)。您可以一頁一頁個別自訂快取存留期,或是一次為所有頁面自訂。

若要進一步全面瞭解快取,我們建議您參考這篇 Google 文章:使用 HTTP 快取來避免不必要的網路要求

任何頁面元件的 getProps 函式都能讓您使用名為 res 的傳入物件自訂 HTTP 回應。若要為單一頁面設定快取存留期,請使用 res 物件的 set 方法來設定 Cache-Control 標頭,並為 max-age 指示詞指定以秒為單位的值。

舉例來說,這個 ProductList 元件將預設的 600 秒快取存留期延長為 900 秒:

我們不建議您在屬於 app/components/_app/index.jsx 中定義的 App 特殊元件之 getProps 函式中,設定 Cache-Control 標頭。App 元件和目前頁面元件的 getProps 函式會同時執行。若您在兩個函式中設定相同的回應標頭,這樣的平行執行將導致無法預測的結果。

您可以在 app/ssr.js 中,為所有頁面設定快取存留期。只要為 defaultCacheTimeSeconds 設定新值,就可以變更預設的快取存留期。如果您需要對 HTTP 標頭進行更精細的控制,請新增 Express 處理常式來設定自訂標頭,例如:

您可以透過 Chrome DevTools 中的「網路」分頁來檢查您的網路要求,測試您的快取控制是否呈現於回應標頭中。或者,您可以在終端機執行以下 curl 命令,輸出所有回應標頭。以您想測試的完整 URL 取代範例命令中的 <URL>,包括任何所需的查詢字串。

為了確保頁面適合 CDN 快取,您必須新增條件式程式碼,來避免在伺服器端轉譯以下類型的內容:

  • 個人化內容,例如使用者名稱、購物車內商品數量、偏好的付款方式。除了單一使用者外,個人化內容並不適合他人,也與他人無關。快取單一使用者的回應並不會提升您的快取命中率。
  • 經常變更的內容,例如產品價格、剩餘庫存、特賣促銷活動。這樣的內容不適合快取,因為當頁面包含已過期資訊時,可能會讓使用者感到混淆。

請將在伺服器端轉譯的頁面視為建置用戶端的通用基礎。將頁面的伺服器端版本快速載入到使用者裝置後,瀏覽器就會接手轉譯個人化和經常變更的內容。

要確定轉譯發生在用戶端還是伺服器端,請檢查 window 物件是否存在,此物件只會在用戶端出現。以下範例使用這項技巧,來只在用戶端轉譯價格:

若要在瀏覽器上預覽在伺服器端轉譯的頁面版本,請將 ?__server_only 附加至 URL。這個查詢參數會停止 Hydration 流程,這樣瀏覽器就不會接手轉譯,而頁面也會在伺服器端轉譯後保持不變。

大部分網店應用程式使用 URL 的查詢字串,來儲存代表應用程式狀態各個方面的參數和值。舉例來說,當使用者搜尋「sweaters」時,您可以在查詢字串中包含搜尋字詞,像這樣:?search=sweaters。查詢字串經常用來追蹤使用者動作。比方說,我們可以為電子郵件中的每一個連結附加獨特的查詢字串,以追蹤與該連結的互動:user=juanita&source=email

在快取方面,並非所有查詢字串參數都相關。Managed Runtime 包含一個稱為「要求處理器」的邊緣函式,讓您能夠在尋找快取回應前,修改要求的查詢字串。您可以透過使用要求處理器,將相似的 URL 對應至同樣的快取回應,增加快取命中率。

若要自訂要求處理器,請編輯 app/request-processor.js 中定義的 processRequest 函式。

以下範例定義了要求處理器,來從查詢字串中過濾掉參數 gclidutm_campaign。這些參數通常與 Google 行銷宣傳活動相關,且僅於用戶端有用。為了簡化查詢字串的處理,其從 PWA Kit React SDK 匯入了 QueryParameters 類別。

用來在快取中尋找相應物件的完整 URL 包含了要求處理器傳回的查詢字串版本。若沒有為該 URL 快取回應,則該 URL 的同一個修改版本將傳遞給 Express 應用程式。

在使用這個方法時,請注意以下兩個地方:

首先,請確定您的應用程式並未依靠任何已過濾掉的參數進行轉譯。舉例來說,如果您在上面過濾掉了 search 參數,就會很難顯示正確的搜尋結果。

其次,從您想重新導向的要求中過濾參數時要小心。若您的程式碼無法存取已過濾掉的參數,則該參數也不能用於重新導向。請想像一個首頁元件,它會把對 www.example.com?lang=en 的要求重新導向至特定於地區設定的路徑,像是 www.example.com/en。如果過濾掉 lang 參數,就無法重新導向至正確的地區設定。

請思考這個序列:

  1. 要求處理器處理了針對 www.example.com/?gclid=123 的要求。
  2. 要求處理器過濾掉 gclid 查詢字串參數。
  3. 要求以完整 URL www.example.com 轉送至應用程式。
  4. 應用程式傳回前往 www.example.com/en 的重新導向。

請注意,在最後一步中,我們失去了原本的 gclid 參數,因此在使用者被重新導向後,瀏覽器將無法使用它。若要避免此問題,請避免過濾掉您想要重新導向的要求的查詢字串。

現在您已經瞭解如何利用不同的技術,改善頁面要求的快取命中率。

請閱讀我們的 Proxy 要求指南,認識快取 API 要求和其他 Proxy 的優點。