快取回應
快取回應對於保持網站的快速性至關重要,無論是頁面還是中介軟體。
預設情況下,建議對所有回應使用 stale-while-revalidate 快取。
例如,我們可以在根 佈局 (src/routes/layout.tsx
) 中新增一個 onGet
匯出,如下所示,以在全站套用良好的快取預設值。
import { component$, Slot } from "@builder.io/qwik";
import type { RequestHandler } from "@builder.io/qwik-city";
export const onGet: RequestHandler = async ({ cacheControl }) => {
cacheControl({
// Always serve a cached response by default, up to a week stale
staleWhileRevalidate: 60 * 60 * 24 * 7,
// Max once every 5 seconds, revalidate on the server to get a fresh version of this page
maxAge: 5,
});
};
export default component$(() => {
return (
<main class="mx-auto max-w-[2200px] relative">
<Slot />
</main>
);
});
透過上述設定,您不僅可以獲得更好的效能(頁面始終從快取中立即提供服務),而且還可以顯著降低託管成本,因為我們的伺服器或邊緣函數每個頁面最多只需要每 5 秒執行一次。
cacheControl
任何採用 請求事件 的方法都可以呼叫 request.cacheControl
來設定回應的快取控制標頭。
import type { RequestHandler } from "@builder.io/qwik-city";
export const onGet: RequestHandler = async ({ cacheControl }) => {
cacheControl({
public: true,
maxAge: 5,
sMaxAge: 10,
staleWhileRevalidate: 60 * 60 * 24 * 365,
});
};
如果您在根目錄設定了預設快取,但想要停用特定頁面的快取,可以使用巢狀佈局覆寫此設定。以下範例覆寫了儀表板頁面的快取。
import type { RequestHandler } from "@builder.io/qwik-city";
// Override caching for /dashboard pages to not cache as they are unique per visitor
export const onGet: RequestHandler = async ({ cacheControl }) => {
cacheControl({
public: false,
maxAge: 0,
sMaxAge: 0,
staleWhileRevalidate: 0,
});
};
您可以查看可以傳遞給 request.cacheControl
的選項的完整 API 參考。
何時不快取
快取通常是有益的,但並非始終適用於每個頁面。如果您的網站上有顯示給不同人員不同內容的網址,例如僅限登入使用者存取的頁面,或根據使用者位置顯示內容的頁面,則應避免使用快取控制標頭來快取這些頁面。而是應根據每個訪問者在伺服器端呈現這些頁面的內容。
對於流量高且對所有人看起來都相同的頁面,例如首頁,快取非常適合用於提升效能和降低成本。對於專為登入使用者設計且流量可能較少的頁面,建議停用快取。
您可以使用任何您喜歡的邏輯有條件地變更快取行為。
import type { RequestHandler } from "@builder.io/qwik-city";
export const onGet: RequestHandler = async ({ cacheControl, url }) => {
// Only our homepage is public and should be CDN cached. Other pages are unique per visitor
if (url.pathname === '/') {
cacheControl({
public: true,
maxAge: 5,
staleWhileRevalidate: 60 * 60 * 24 * 365,
});
}
};
CDN 快取控制
為了更好地控制您的快取策略,您的 CDN 可能還有另一層快取控制標頭。
cacheControl
便利方法可以接收第二個參數(預設設定為 "Cache-Control"
)。您可以傳入任何特定於您的 CDN 的字串值,例如 "CDN-Cache-Control"、"Cloudflare-CDN-Cache-Control"、"Vercel-CDN-Cache-Control" 等。
cacheControl({
maxAge: 5,
staleWhileRevalidate: 60 * 60 * 24 * 365,
}, "CDN-Cache-Control");
遺漏的控制
某些 CDN(例如 Vercel Edge)可能會刪除您的一些「快取控制」標頭。
如果您在沒有 CDN-Cache-Control 的情況下設定了 Cache-Control,則 Vercel Edge 網路會在將回應發送到瀏覽器之前,從回應中刪除 s-maxage 和 stale-while-revalidate。要確定回應是否從快取提供服務,請檢查回應中的 x-vercel-cache 標頭。
如果您的 CDN(例如 Vercel Edge)自動刪除了某些快取控制標頭,並且您希望在瀏覽器中實作「stale-while-revalidate」或「s-maxage」等快取策略,則可以指定其他 cacheControl。
import type { RequestHandler } from "@builder.io/qwik-city";
export const onGet: RequestHandler = async ({ cacheControl }) => {
// If you want the browser to use "stale-while-revalidate" or "s-maxage" Cache Control headers, you have to add the second cacheControl with "CDN-Cache-Control" or "Vercel-CDN-Cache-Control" on Vercel Edge
cacheControl({
staleWhileRevalidate: 60 * 60 * 24 * 365,
maxAge: 5,
});
cacheControl({
maxAge: 5,
staleWhileRevalidate: 60 * 60 * 24 * 365,
}, "CDN-Cache-Control");
};