此文已使用 Salesforce 機器翻譯系統翻譯。更多詳細資料請參見此處。
改善網店成效的最佳方式之一,就是最大化您的快取命中率。任何可以從 Managed Runtime 的 CDN 快取中完成的要求,都可以視為快取命中。每次快取命中都能讓您加快使用者的頁面載入速度,因為您節省了在伺服器端轉譯頁面、以及向後端系統和 API 發出要求的成本。
這份指南介紹了最大化快取命中率的三種不同技術:設定最佳快取存留期、條件式轉譯、篩選查詢字串。讓我們來仔細看看每種技術。
快取 HTTP 要求的最佳期間會根據要求內容而定。載入不常變更之內容頁面的要求可以穩定地快取很長一段時間。相反地,經常更新產品的產品清單頁面可能需要較短的快取存留期,例如 15 分鐘。可以的話,盡量選擇較長的快取存留期,以最大化快取命中率。
HTTP 回應中的 Cache-Control 標頭決定了對頁面要求的回應儲存在 CDN 快取中的時間長度。PWA Kit 專案中的頁面回應預設快取存留期為 600 秒 (10 分鐘)。您可以一頁一頁個別自訂快取存留期,或是一次為所有頁面自訂。
若要進一步全面瞭解快取,我們建議您參考這篇 Google 文章:使用 HTTP 快取來避免不必要的網路要求。
Tip
任何頁面元件的 getProps 函式都能讓您使用名為 res 的傳入物件自訂 HTTP 回應。若要為單一頁面設定快取存留期,請使用 res 物件的 set 方法來設定 Cache-Control 標頭,並為 max-age 指示詞指定以秒為單位的值。
舉例來說,這個 ProductList 元件將預設的 600 秒快取存留期延長為 900 秒:
1ProductList.getProps = async ({res, params, location, api}) => {
2 const {categoryId} = params
3 const urlParams = new URLSearchParams(location.search)
4
5 // Set the cache-control header values to align with the Commerce API settings.
6 if (res) {
7 res.set('Cache-Control', 'public, must-revalidate, max-age=900')
8 }
9
10 // The rest of the getProps function, including the return statement, goes here.
11}我們不建議您在屬於 app/components/_app/index.jsx 中定義的 App 特殊元件之 getProps 函式中,設定 Cache-Control 標頭。App 元件和目前頁面元件的 getProps 函式會同時執行。若您在兩個函式中設定相同的回應標頭,這樣的平行執行將導致無法預測的結果。
Note
您可以在 app/ssr.js 中,為所有頁面設定快取存留期。只要為 defaultCacheTimeSeconds 設定新值,就可以變更預設的快取存留期。如果您需要對 HTTP 標頭進行更精細的控制,請新增 Express 處理常式來設定自訂標頭,例如:
1app.get('/*', (req, res) => {
2 res.set('Cache-Control', 'public, max-age=3600')
3 render(req, res)
4})您可以透過 Chrome DevTools 中的「網路」分頁來檢查您的網路要求,測試您的快取控制是否呈現於回應標頭中。或者,您可以在終端機執行以下 curl 命令,輸出所有回應標頭。以您想測試的完整 URL 取代範例命令中的
1curl --dump-header - --silent --output /dev/null <URL>為了確保頁面適合 CDN 快取,您必須新增條件式程式碼,來避免在伺服器端轉譯以下類型的內容:
請將在伺服器端轉譯的頁面視為建置用戶端的通用基礎。將頁面的伺服器端版本快速載入到使用者裝置後,瀏覽器就會接手轉譯個人化和經常變更的內容。
要確定轉譯發生在用戶端還是伺服器端,請檢查 window 物件是否存在,此物件只會在用戶端出現。以下範例使用這項技巧,來只在用戶端轉譯價格:
1<div>
2 {/* The price is only rendered on the client side,
3 * because it changes frequently */}
4 {typeof window != 'undefined' && <p>Price: ${price}</p>}
5</div>若要在瀏覽器上預覽在伺服器端轉譯的頁面版本,請將 ?__server_only 附加至 URL。這個查詢參數會停止 Hydration 流程,這樣瀏覽器就不會接手轉譯,而頁面也會在伺服器端轉譯後保持不變。
Tip
大部分網店應用程式使用 URL 的查詢字串,來儲存代表應用程式狀態各個方面的參數和值。舉例來說,當使用者搜尋「sweaters」時,您可以在查詢字串中包含搜尋字詞,像這樣:?search=sweaters。查詢字串經常用來追蹤使用者動作。比方說,我們可以為電子郵件中的每一個連結附加獨特的查詢字串,以追蹤與該連結的互動:user=juanita&source=email。
在快取方面,並非所有查詢字串參數都相關。Managed Runtime 包含一個稱為「要求處理器」的邊緣函式,讓您能夠在尋找快取回應前,修改要求的查詢字串。您可以透過使用要求處理器,將相似的 URL 對應至同樣的快取回應,增加快取命中率。
若要自訂要求處理器,請編輯 app/request-processor.js 中定義的 processRequest 函式。
以下範例定義了要求處理器,來從查詢字串中過濾掉參數 gclid 和 utm_campaign。這些參數通常與 Google 行銷宣傳活動相關,且僅於用戶端有用。為了簡化查詢字串的處理,其從 PWA Kit React SDK 匯入了 QueryParameters 類別。
1import {QueryParameters} from 'pwa-kit-react-sdk/utils/ssr-request-processing'
2
3const filterQueryStringKeys = (querystring, filteredKeys) =>
4 QueryParameters.from(
5 new QueryParameters(querystring).parameters.filter(({key}) => !filteredKeys.includes(key))
6 ).toString()
7
8export const processRequest = ({path, querystring}) => ({
9 path,
10 querystring: filterQueryStringKeys(querystring, ['gclid', 'utm_campaign']),
11})用來在快取中尋找相應物件的完整 URL 包含了要求處理器傳回的查詢字串版本。若沒有為該 URL 快取回應,則該 URL 的同一個修改版本將傳遞給 Express 應用程式。
在使用這個方法時,請注意以下兩個地方:
首先,請確定您的應用程式並未依靠任何已過濾掉的參數進行轉譯。舉例來說,如果您在上面過濾掉了 search 參數,就會很難顯示正確的搜尋結果。
其次,從您想重新導向的要求中過濾參數時要小心。若您的程式碼無法存取已過濾掉的參數,則該參數也不能用於重新導向。請想像一個首頁元件,它會把對 www.example.com?lang=en 的要求重新導向至特定於地區設定的路徑,像是 www.example.com/en。如果過濾掉 lang 參數,就無法重新導向至正確的地區設定。
請思考這個序列:
www.example.com/?gclid=123 的要求。gclid 查詢字串參數。www.example.com 轉送至應用程式。www.example.com/en 的重新導向。請注意,在最後一步中,我們失去了原本的 gclid 參數,因此在使用者被重新導向後,瀏覽器將無法使用它。若要避免此問題,請避免過濾掉您想要重新導向的要求的查詢字串。
現在您已經瞭解如何利用不同的技術,改善頁面要求的快取命中率。
請閱讀我們的 Proxy 要求指南,認識快取 API 要求和其他 Proxy 的優點。