banner
innei

innei

写代码是因为爱,写到世界充满爱!
github
telegram
twitter

キャッシュヘッダーとエッジネットワークを利用したアクセスの高速化

本文は Cloudflare + Vercel の例です。

キャッシュヘッダーの理解#

本番環境では、通常 Redis を利用してインターフェースデータをキャッシュします。フロントエンドアプリケーションでは、一般的にコンテンツ配信ネットワーク(CDN)を利用してページやその他の静的リソースをキャッシュします。

HTTP ヘッダー cache-control はリソースを強制的にキャッシュするために使用できることがわかっています。

例えば、cache-control: max-age=60 はリソースが 60 秒間は期限切れにならないことを示し、ブラウザが強制的にリフレッシュしない限り(例えば、リクエストヘッダーに cache-control: max-age=0 が含まれている場合)、ローカルキャッシュを直接使用できます。

エッジネットワークやコンテンツ配信ネットワークでは、一般的に関連するヘッダーを使用してキャッシュを行います。

例えば:s-maxage の値。

Note

s-maxage

s-maxage レスポンスディレクティブは、レスポンスが共有キャッシュ内でどれくらい新鮮であるかを示します。s-maxage ディレクティブはプライベートキャッシュによって無視され、共有キャッシュに対して max-age ディレクティブまたは Expires ヘッダーで指定された値をオーバーライドします。

Cache-Control: s-maxage=604800

参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage

この値は、一般的に CDN またはエッジネットワークによってキャッシュ時間を制御するために使用されます。

Vercel では。Cache セクションで、この値を使用して API レスポンスのキャッシュ時間を制御できることが示されています。また、Vercel のプライベート HTTP ヘッダーも提供されています。例えば Vercel-CDN-Cache-Control

Cloudflare では、When to use CDN-Cache-Control の例がリソースの各端でのキャッシュ制御を理解するのに役立ちます。

Headers:

Cache-Control: max-age=14400, s-maxage=84000
Cloudflare-CDN-Cache-Control: max-age=24400
CDN-Cache-Control: max-age=18000

キャッシュの動作:

キャッシュキャッシュ TTL (秒)
オリジンサーバーキャッシュ14400
ネットワーク共有キャッシュ84000
Cloudflare エッジ24400
その他の CDN18000
ブラウザキャッシュ14400

上表では、Cloudflare がレスポンスヘッダーの cache-control: s-maxageCloudflare-CDN-Cache-Control を使用して、Cloudflare 配信ネットワークとエッジネットワークでのリソースのキャッシュを制御できることが示されています。

キャッシュヘッダーを使用することで、ユーザーがリソースにより早くアクセスでき、サーバーの負荷を軽減できます。

Vercel にデプロイされた Next.js の例として、次に短期的な同時負荷の下でサーバーへの実際のリクエストを減らすための最適化を行います。

Next.js API ルートのレスポンスキャッシュ#

これはシンプルな Next.js API ルートです。

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export const GET = async (req: NextRequest) => {
  return NextResponse.json({})
}

現在、キャッシュヘッダーを追加できます。

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export const GET = async (req: NextRequest) => {
  return NextResponse.json(
    {},
    {
      headers: {
        'Cache-Control': 'max-age=60, s-maxage=86400',
        'CDN-Cache-Control': 'max-age=86400',
      },
    },
  )
}

現在、API を Cloudflare プロキシを使用します。

最初のリクエストの後、次のリクエストで、Cloudflare がキャッシュにヒットしたことがわかります。

Cf-Cache-Status: HIT

vercel.json を使用したグローバルヘッダーの設定#

単一の API で毎回キャッシュヘッダーを追加するのは非常に面倒であり、API ルート以外の他のルートを制御することもできません。vercel.json を使用してグローバルヘッダーを設定できます。

プロジェクトのルートディレクトリに vercel.json を新規作成し、内容は以下の通りです:

以下のルートはプロジェクト Shiro を参考にしており、必要に応じてルートを設定できます。

{
  "headers": [
    {
      "source": "/",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "s-maxage=300, stale-while-revalidate=59"
        },
        {
          "key": "CDN-Cache-Control",
          "value": "max-age=300"
        },
        {
          "key": "Vercel-CDN-Cache-Control",
          "value": "max-age=300"
        }
      ]
    },
    {
      "source": "/og",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "s-maxage=3600, stale-while-revalidate=30"
        },
        {
          "key": "CDN-Cache-Control",
          "value": "max-age=3600"
        },
        {
          "key": "Vercel-CDN-Cache-Control",
          "value": "max-age=3600"
        }
      ]
    },
    {
      "source": "/api/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "s-maxage=60, stale-while-revalidate=30"
        },
        {
          "key": "CDN-Cache-Control",
          "value": "max-age=60"
        },
        {
          "key": "Vercel-CDN-Cache-Control",
          "value": "max-age=60"
        }
      ]
    },
    {
      "source": "/feed",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "s-maxage=86400, stale-while-revalidate=3600"
        },
        {
          "key": "CDN-Cache-Control",
          "value": "max-age=86400"
        },
        {
          "key": "Vercel-CDN-Cache-Control",
          "value": "max-age=86400"
        }
      ]
    }
  ]
}

Vercel が提供する設定を使用することで、各ルートに対してキャッシュヘッダーを設定できます。設定後、Vercel はこれらのリクエストに応答する際に自動的にキャッシュヘッダーを追加し、その後 Cloudflare がキャッシュヘッダーを読み取り、Cloudflare ネットワークでキャッシュを行い、次回のリクエストが到達した際には直接 Cloudflare キャッシュから読み取ります。

また、stale-while-revalidate= の値は、リソースが期限切れになった後、どれくらいの間に期限切れのリソースを使用できるかを制御し、その後バックグラウンドで非同期にリソースを更新します。これにより、たとえ期限切れのシナリオでも、ユーザーは迅速にリソースを取得でき、ページの読み込みが速くなります。

[!IMPORTANT]

ルートのマッチングは下から上に行われるため、最初の項目はグローバルフォールバックとして定義でき、ルートマッチング /(.*) となります。

参考:https://vercel.com/docs/projects/project-configuration#headers

Vercel エッジネットワークキャッシュ#

Vercel-CDN-Cache-Control というヘッダーに気づいたかもしれません。このヘッダーは Vercel のプライベートヘッダーで、Vercel エッジネットワークでのリソースのキャッシュを制御するために使用されます。Vercel もキャッシュを提供しているのに、なぜ Cloudflare を使用するのでしょうか?

おそらく以下の理由が考えられます:

  1. Cloudflare は一般的に DNS プロバイダーとして機能し、より迅速な応答時間を持っています。
  2. Vercel のキャッシュヒットは奇妙で、時にはヒットし、時にはヒットしないことがあり、私を困惑させます。一方、Cloudflare のキャッシュヒットはドキュメントに従い、予想通りです。

この記事は Mix Space によって xLog に同期更新されました。原文リンクは https://innei.in/posts/tech/vercel-cloudflare-http-header-about-cache

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。