レスポンスのキャッシング
レスポンスのキャッシングは、ページとミドルウェアの両方において、サイトをできるだけ高速に保つために不可欠です。
すべてのレスポンスに対して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秒に1回だけ実行する必要があるためです。
`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リファレンスを参照してください。
キャッシュしない場合
キャッシングは一般的に有益ですが、すべてのページに常に適しているわけではありません。サイトに、ログインしているユーザー専用のページや、ユーザーの場所に基づいてコンテンツを表示するページなど、ユーザーごとに異なるコンテンツを表示するURLがある場合は、キャッシュ制御ヘッダーを使用してこれらのページをキャッシュしないでください。代わりに、これらのページのコンテンツを訪問者ごとにサーバー側でレンダリングしてください。
ホームページなど、すべての人に見えるトラフィック量の多いページでは、キャッシングはパフォーマンスの向上とコストの削減に役立ちます。トラフィックが少ないログインユーザー専用のページでは、キャッシングを無効にすることをお勧めします。
任意のロジックを使用して、キャッシュの動作を条件付きで変更できます。
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`コンビニエンスメソッドは、2番目の引数を受け取ることができます(デフォルトでは` "Cache-Control "`に設定されています)。" CDN-Cache-Control "、" Cloudflare-CDN-Cache-Control "、" Vercel-CDN-Cache-Control "など、CDNに固有の文字列値を渡すことができます。
cacheControl({
maxAge: 5,
staleWhileRevalidate: 60 * 60 * 24 * 365,
}, "CDN-Cache-Control");
不足している制御
一部のCDN(Vercel Edgeなど)は、「Cache-Control」ヘッダーの一部を削除する場合があります。
CDN-Cache-Controlを指定せずにCache-Controlを設定した場合、Vercel Edge Networkは、レスポンスをブラウザに送信する前に、s-maxageとstale-while-revalidateをレスポンスから削除します。レスポンスがキャッシュから提供されたかどうかを判断するには、レスポンスのx-vercel-cacheヘッダーを確認してください。
Vercel EdgeなどのCDNが特定のキャッシュ制御ヘッダーを自動的に削除し、ブラウザで「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");
};