レスポンスのキャッシング

レスポンスのキャッシングは、ページミドルウェアの両方において、サイトをできるだけ高速に保つために不可欠です。

すべてのレスポンスに対してstale-while-revalidateキャッシングを使用することをお勧めします。

たとえば、ルートレイアウト(`src/routes/layout.tsx`)に`onGet`エクスポートを追加することで、サイト全体に適切なキャッシングのデフォルトを適用できます。

src/routes/layout.tsx
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`を呼び出して、レスポンスのキャッシュ制御ヘッダーを設定できます。

src/routes/layout.tsx
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,
  });
};

ルートにデフォルトのキャッシングが設定されているが、特定のページのキャッシングを無効にしたい場合は、ネストされたレイアウトを使用してこの設定をオーバーライドできます。以下の例では、ダッシュボードページのキャッシングをオーバーライドしています。

src/routes/dashboard/layout.tsx
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がある場合は、キャッシュ制御ヘッダーを使用してこれらのページをキャッシュしないでください。代わりに、これらのページのコンテンツを訪問者ごとにサーバー側でレンダリングしてください。

ホームページなど、すべての人に見えるトラフィック量の多いページでは、キャッシングはパフォーマンスの向上とコストの削減に役立ちます。トラフィックが少ないログインユーザー専用のページでは、キャッシングを無効にすることをお勧めします。

任意のロジックを使用して、キャッシュの動作を条件付きで変更できます。

src/routes/layout.tsx
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」ヘッダーの一部を削除する場合があります。

Vercelのドキュメントでは、

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を指定できます。

src/routes/layout.tsx
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");
};

貢献者

このドキュメントの改善に貢献してくれたすべての貢献者に感謝します!

  • steve8708
  • harishkrishnan24
  • maiieul
  • igorbabko
  • mrhoodz
  • mhevery
  • chsanch
  • hamatoyogi
  • Jemsco