HTTP Cache

The nature of rich web applications means that they're dynamic. No matter how efficient your application, each request will always contain more overhead than serving a static file. Usually, that's fine. But when you need your requests to be lightning fast, you need HTTP caching.

リッチ Web アプリケーションの性質は、それらが動的であることを意味します。アプリケーションがどれほど効率的であっても、各リクエストには常に、静的ファイルを提供するよりも多くのオーバーヘッドが含まれます。通常、それで問題ありません。しかし、リクエストを超高速にする必要がある場合は、HTTP キャッシュが必要です。

Caching on the Shoulders of Giants

With HTTP Caching, you cache the full output of a page (i.e. the response) and bypass your application entirely on subsequent requests. Caching entire responses isn't always possible for highly dynamic sites, or is it? With Edge Side Includes (ESI), you can use the power of HTTP caching on only fragments of your site.

HTTP キャッシングを使用すると、ページの完全な出力 (つまり、応答) をキャッシュし、後続の要求でアプリケーションを完全にバイパスします。非常に動的なサイトでは、応答全体をキャッシュすることは常に可能であるとは限りませんか? Edge Side includes (ESI) を使用すると、サイトのフラグメントのみで HTTP キャッシングの機能を使用できます。

The Symfony cache system is different because it relies on the simplicity and power of the HTTP cache as defined in RFC 7234 - Caching. Instead of reinventing a caching methodology, Symfony embraces the standard that defines basic communication on the Web. Once you understand the fundamental HTTP validation and expiration caching models, you'll be ready to master the Symfony cache system.

Symfony キャッシュ システムは、RFC 7234 - キャッシングで定義されている HTTP キャッシュのシンプルさとパワーに依存しているため、他とは異なります。キャッシング方法論を再発明する代わりに、Symfony は Web 上の基本的な通信を定義する標準を採用しています。基本的な HTTPvalidation と有効期限キャッシング モデルを理解したら、Symfonycache システムをマスターする準備が整います。

Since caching with HTTP isn't unique to Symfony, many articles already exist on the topic. If you're new to HTTP caching, Ryan Tomayko's article Things Caches Do is highly recommended. Another in-depth resource is Mark Nottingham's Cache Tutorial.

HTTP によるキャッシュは Symfony に固有のものではないため、このトピックに関する多くの記事が既に存在します。 HTTP キャッシングを初めて使用する場合は、Ryan Tomayko の記事Things Caches Do を強くお勧めします。もう 1 つの詳細なリソースは、MarkNottingham の Cache Tutorial です。

Caching with a Gateway Cache

When caching with HTTP, the cache is separated from your application entirely and sits between your application and the client making the request.

HTTP でキャッシュする場合、キャッシュはアプリケーションから完全に分離され、アプリケーションとリクエストを行うクライアントの間に置かれます。

The job of the cache is to accept requests from the client and pass them back to your application. The cache will also receive responses back from your application and forward them on to the client. The cache is the "middle-man" of the request-response communication between the client and your application.

キャッシュの役割は、クライアントからのリクエストを受け取り、それらをアプリケーションに戻すことです。また、キャッシュはアプリケーションから返された応答を受け取り、それらをクライアントに転送します。キャッシュは、クライアントとアプリケーション間のリクエスト/レスポンス通信の「仲介者」です。

Along the way, the cache will store each response that is deemed "cacheable" (See HTTP Cache). If the same resource is requested again, the cache sends the cached response to the client, ignoring your application entirely.

その過程で、キャッシュは「キャッシュ可能」と見なされる各応答を保存します (HTTP キャッシュを参照)。同じリソースが再度要求された場合、キャッシュはアプリケーションを完全に無視して、キャッシュされた応答をクライアントに送信します。

This type of cache is known as an HTTP gateway cache and many exist such as Varnish, Squid in reverse proxy mode, and the Symfony reverse proxy.

このタイプのキャッシュは HTTP ゲートウェイ キャッシュとして知られており、Varnish、リバース プロキシ モードの Squid、Symfony リバース プロキシなど、多くのキャッシュが存在します。

Tip

ヒント

Gateway caches are sometimes referred to as reverse proxy caches, surrogate caches, or even HTTP accelerators.

ゲートウェイ キャッシュは、リバース プロキシ キャッシュ、代理キャッシュ、または HTTP アクセラレータと呼ばれることもあります。

Symfony Reverse Proxy

Symfony comes with a reverse proxy (i.e. gateway cache) written in PHP. It's not a fully-featured reverse proxy cache like Varnish, but it is a great way to start.

Symfony には、PHP で書かれたリバース プロキシ (つまり、ゲートウェイ キャッシュ) が付属しています。これは、Varnish のような完全な機能を備えたリバース プロキシ キャッシュではありませんが、始めるには最適な方法です。

Tip

ヒント

For details on setting up Varnish, see How to Use Varnish to Speed up my Website.

Varnish の設定の詳細については、Varnish を使用して Web サイトを高速化する方法を参照してください。

Use the framework.http_cache option to enable the proxy for the prod environment:

Framework.http_cache オプションを使用して、prod 環境のプロキシを有効にします。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/framework.yaml
when@prod:
    framework:
        http_cache: true

The kernel will immediately act as a reverse proxy: caching responses from your application and returning them to the client.

カーネルはすぐにリバース プロキシとして機能し、アプリケーションからの応答をキャッシュしてクライアントに返します。

The proxy has a sensible default configuration, but it can be finely tuned via a set of options.

プロキシには適切なデフォルト構成がありますが、一連のオプションを使用して微調整できます。

When in debug mode, Symfony automatically adds an X-Symfony-Cache header to the response. You can also use the trace_level config option and set it to either none, short or full to add this information.

デバッグモードの場合、Symfony は X-Symfony-Cache ヘッダーを応答に自動的に追加します。また、trace_levelconfig オプションを使用して、none、short、または full に設定して、この情報を追加することもできます。

short will add the information for the main request only. It's written in a concise way that makes it easy to record the information in your server log files. For example, in Apache you can use %{X-Symfony-Cache}o in LogFormat format statements. This information can be used to extract general information about cache efficiency of your routes.

short は、メイン リクエストの情報のみを追加します。簡潔な方法で記述されているため、サーバー ログ ファイルに情報を簡単に記録できます。たとえば、Apache では、LogFormat 形式のステートメントで %{X-Symfony-Cache}o を使用できます。この情報は、ルートのキャッシュ効率に関する一般的な情報を抽出するために使用できます。

Tip

ヒント

You can change the name of the header used for the trace information using the trace_header config option.

trace_header 構成オプションを使用して、トレース情報に使用されるヘッダーの名前を変更できます。
あるリバース プロキシから別のリバース プロキシへの変更

The Symfony reverse proxy is a great tool to use when developing your website or when you deploy your website to a shared host where you cannot install anything beyond PHP code. But being written in PHP, it cannot be as fast as a proxy written in C.

Symfony リバース プロキシは、Web サイトを開発するとき、または PHP コード以外をインストールできない共有ホストに Web サイトを展開するときに使用する優れたツールです。ただし、PHP で記述されているため、C で記述されたプロキシほど高速ではありません。

Fortunately, since all reverse proxies are effectively the same, you should be able to switch to something more robust - like Varnish - without any problems. See How to use Varnish

幸いなことに、すべてのリバース プロキシは事実上同じであるため、より堅牢なもの (Varnish など) に問題なく切り替えることができるはずです。Varnish の使用方法を参照してください。

Making your Responses HTTP Cacheable

Once you've added a reverse proxy cache (e.g. like the Symfony reverse proxy or Varnish), you're ready to cache your responses. To do that, you need to communicate to your cache which responses are cacheable and for how long. This is done by setting HTTP cache headers on the response.

リバース プロキシ キャッシュ (Symfony リバース プロキシや Varnish など) を追加したら、応答をキャッシュする準備が整います。そのためには、キャッシュ可能な応答とその期間を yourcache に伝える必要があります。これは、応答に HTTPcache ヘッダーを設定することによって行われます。

HTTP specifies four response cache headers that you can set to enable caching:

HTTP は、キャッシュを有効にするために設定できる 4 つの応答キャッシュ ヘッダーを指定します。
  • Cache-Control
    キャッシュ制御
  • Expires
    期限切れ
  • ETag
    ETag
  • Last-Modified
    最終更新日

These four headers are used to help cache your responses via two different models:

これら 4 つのヘッダーは、2 つの異なるモデルを介して応答をキャッシュするために使用されます。
  1. Expiration Caching Used to cache your entire response for a specific amount of time (e.g. 24 hours). Simple, but cache invalidation is more difficult.
    有効期限のキャッシュ特定の時間 (24 時間など) の間、応答全体をキャッシュするために使用されます。単純ですが、キャッシュの無効化はより困難です。
  2. Validation Caching More complex: used to cache your response, but allows you to dynamically invalidate it as soon as your content changes.
    検証キャッシュより複雑: 応答をキャッシュするために使用されますが、コンテンツが変更されるとすぐに動的に無効にすることができます。
HTTP 仕様を読む

All of the HTTP headers you'll read about are not invented by Symfony! They're part of an HTTP specification that's used by sites all over the web. To dig deeper into HTTP Caching, check out the documents RFC 7234 - Caching and RFC 7232 - Conditional Requests.

これから読むすべての HTTP ヘッダーは、Symfony によって発明されたものではありません!これらは、Web 全体のサイトで使用される HTTP 仕様の一部です。 HTTP キャッシングをより深く掘り下げるには、ドキュメント RFC 7234 - Caching およびRFC 7232 - Conditional Requests を確認してください。

As a web developer, you are strongly urged to read the specification. Its clarity and power - even more than fifteen years after its creation - is invaluable. Don't be put-off by the appearance of the spec - its contents are much more beautiful than its cover!

Web 開発者として、仕様を読むことを強くお勧めします。その透明性とパワーは、作成から 15 年以上経っても非常に貴重です。仕様の外観に惑わされないでください - その内容はその表紙よりもはるかに美しいです!

Expiration Caching

The easiest way to cache a response is by caching it for a specific amount of time:

応答をキャッシュする最も簡単な方法は、特定の時間キャッシュすることです。
  • Attributes
    属性
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
// src/Controller/BlogController.php
use Symfony\Component\HttpKernel\Attribute\Cache;
// ...

#[Cache(public: true, maxage: 3600, mustRevalidate: true)]
public function index(): Response
{
    return $this->render('blog/index.html.twig', []);
}

6.2

6.2

The #[Cache()] attribute was introduced in Symfony 6.2.

#[Cache()] 属性は Symfony 6.2 で導入されました。

Thanks to this new code, your HTTP response will have the following header:

この新しいコードのおかげで、HTTP 応答には次のヘッダーが含まれます。
1
Cache-Control: public, maxage=3600, must-revalidate

This tells your HTTP reverse proxy to cache this response for 3600 seconds. If anyone requests this URL again before 3600 seconds, your application won't be hit at all. If you're using the Symfony reverse proxy, look at the X-Symfony-Cache header for debugging information about cache hits and misses.

これにより、HTTP リバース プロキシがこの応答を 3600 秒間キャッシュするように指示されます。誰かがこの URL を 3600 秒前に再度リクエストしても、アプリケーションはまったくヒットしません。Symfony リバース プロキシを使用している場合は、X-Symfony-Cache ヘッダーでキャッシュ ヒットとキャッシュ ミスに関するデバッグ情報を確認してください。

Tip

ヒント

The URI of the request is used as the cache key (unless you vary).

要求の URI がキャッシュ キーとして使用されます (変更しない限り)。

This provides great performance and is simple to use. But, cache invalidation is not supported. If your content change, you'll need to wait until your cache expires for the page to update.

これにより、優れたパフォーマンスが提供され、使いやすくなります。ただし、キャッシュの無効化はサポートされていません。コンテンツが変更された場合、ページが更新されるまでキャッシュの有効期限が切れるまで待つ必要があります。

Tip

ヒント

Actually, you can manually invalidate your cache, but it's not part of the HTTP Caching spec. See Cache Invalidation.

実際には、手動でキャッシュを無効にすることができますが、それは HTTP キャッシング仕様の一部ではありません。キャッシュの無効化を参照してください。

If you need to set cache headers for many different controller actions, check out FOSHttpCacheBundle. It provides a way to define cache headers based on the URL pattern and other request properties.

多くの異なるコントローラー アクションにキャッシュ ヘッダーを設定する必要がある場合は、FOSHttpCacheBundle を確認してください。 URLpattern およびその他の要求プロパティに基づいてキャッシュ ヘッダーを定義する方法を提供します。

Finally, for more information about expiration caching, see HTTP Cache Expiration.

最後に、有効期限キャッシュの詳細については、HTTP キャッシュの有効期限を参照してください。

Validation Caching

With expiration caching, you say "cache for 3600 seconds!". But, when someone updates cached content, you won't see that content on your site until the cache expires.

有効期限キャッシュでは、「3600 秒間キャッシュします!」と言います。ただし、誰かがキャッシュされたコンテンツを更新すると、キャッシュが期限切れになるまでそのコンテンツはサイトに表示されません。

If you need to see updated content immediately, you either need to invalidate your cache or use the validation caching model.

更新されたコンテンツをすぐに表示する必要がある場合は、キャッシュを無効にするか、validationcaching モデルを使用する必要があります。

For details, see HTTP Cache Validation.

詳細については、HTTP キャッシュの検証を参照してください。

Safe Methods: Only caching GET or HEAD requests

HTTP caching only works for "safe" HTTP methods (like GET and HEAD). This means three things:

HTTP キャッシングは、「安全な」HTTP メソッド (GET や HEAD など) に対してのみ機能します。これは次の 3 つのことを意味します。
  • Don't try to cache PUT or DELETE requests. It won't work and with good reason. These methods are meant to be used when mutating the state of your application (e.g. deleting a blog post). Caching them would prevent certain requests from hitting and mutating your application.
    PUT または DELETE リクエストをキャッシュしようとしないでください。これらのメソッドは、アプリケーションの状態を変更する場合 (ブログ投稿の削除など) に使用することを意図しています。それらをキャッシュすると、特定のリクエストがアプリケーションにヒットして変更されるのを防ぐことができます。
  • POST requests are generally considered uncacheable, but they can be cached when they include explicit freshness information. However, POST caching is not widely implemented, so you should avoid it if possible.
    POST リクエストは一般にキャッシュ不可と見なされますが、明示的な鮮度情報が含まれている場合はキャッシュできます。ただし、POST キャッシングは広く実装されているわけではないため、可能であれば使用を避ける必要があります。
  • You should never change the state of your application (e.g. update a blog post) when responding to a GET or HEAD request. If those requests are cached, future requests may not actually hit your server.
    GET または HEAD リクエストに応答するときは、アプリケーションの状態を決して変更しないでください (ブログ投稿を更新するなど)。これらのリクエストがキャッシュされている場合、将来のリクエストが実際にサーバーにヒットしない可能性があります。

More Response Methods

The Response class provides many more methods related to the cache. Here are the most useful ones:

Response クラスは、キャッシュに関連するさらに多くのメソッドを提供します。最も便利なものは次のとおりです。
1
2
3
4
5
// marks the Response stale
$response->expire();

// forces the response to return a proper 304 response with no content
$response->setNotModified();

Additionally, most cache-related HTTP headers can be set via the single setCache() method:

さらに、ほとんどのキャッシュ関連の HTTP ヘッダーは、singlesetCache() メソッドを介して設定できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// use this method to set several cache settings in one call
// (this example lists all the available cache settings)
$response->setCache([
    'must_revalidate'  => false,
    'no_cache'         => false,
    'no_store'         => false,
    'no_transform'     => false,
    'public'           => true,
    'private'          => false,
    'proxy_revalidate' => false,
    'max_age'          => 600,
    's_maxage'         => 600,
    'immutable'        => true,
    'last_modified'    => new \DateTime(),
    'etag'             => 'abcdef'
]);

Tip

ヒント

All these options are also available when using the #[Cache()] attribute.

これらすべてのオプションは、#[Cache()] 属性を使用する場合にも使用できます。

Cache Invalidation

Cache invalidation is not part of the HTTP specification. Still, it can be really useful to delete various HTTP cache entries as soon as some content on your site is updated.

キャッシュの無効化は、HTTP 仕様の一部ではありません。それでも、サイトのコンテンツが更新されたらすぐに、さまざまな HTTP キャッシュ エントリを削除すると非常に便利です。

For details, see Cache Invalidation.

詳細については、キャッシュの無効化を参照してください。

Using Edge Side Includes

When pages contain dynamic parts, you may not be able to cache entire pages, but only parts of it. Read Working with Edge Side Includes to find out how to configure different cache strategies for specific parts of your page.

ページに動的パーツが含まれている場合、ページ全体をキャッシュすることはできず、ページの一部のみをキャッシュすることができます。ページの特定の部分に対してさまざまなキャッシュ戦略を構成する方法については、「エッジ サイド インクルードの操作」を参照してください。

HTTP Caching and User Sessions

Whenever the session is started during a request, Symfony turns the response into a private non-cacheable response. This is the best default behavior to not cache private user information (e.g. a shopping cart, a user profile details, etc.) and expose it to other visitors.

リクエスト中にセッションが開始されるたびに、Symfony はレスポンスをキャッシュ不可のプライベートなレスポンスに変換します。これは、プライベートなユーザー情報 (ショッピング カート、ユーザー プロファイルの詳細など) をキャッシュせず、他の訪問者に公開するための最適なデフォルトの動作です。

However, even requests making use of the session can be cached under some circumstances. For example, information related to some user group could be cached for all the users belonging to that group. Handling these advanced caching scenarios is out of the scope of Symfony, but they can be solved with the FOSHttpCacheBundle.

ただし、セッションを使用するリクエストでも、状況によってはキャッシュされる可能性があります。たとえば、あるユーザー グループに関連する情報を、そのグループに属するすべてのユーザーに対してキャッシュすることができます。これらの高度なキャッシング シナリオの処理は Symfony の範囲外ですが、FOSHttpCacheBundle で解決できます。

In order to disable the default Symfony behavior that makes requests using the session uncacheable, add the following internal header to your response and Symfony won't modify it:

セッションを使用するリクエストをキャッシュ不可にするデフォルトの Symfony の動作を無効にするには、次の内部ヘッダーをレスポンスに追加します。Symfony はそれを変更しません:
1
2
3
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;

$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');

Summary

Symfony was designed to follow the proven rules of the road: HTTP. Caching is no exception. Mastering the Symfony cache system means becoming familiar with the HTTP cache models and using them effectively. This means that, instead of relying only on Symfony documentation and code examples, you have access to a world of knowledge related to HTTP caching and gateway caches such as Varnish.

symfony は、実証済みのルールである HTTP に従うように設計されています。キャッシングも例外ではありません。 Symfony キャッシュ システムをマスターするということは、HTTP キャッシュ モデルに精通し、それらを効果的に使用することを意味します。これは、Symfony のドキュメントとコード例だけに頼るのではなく、HTTP キャッシングや Varnish などのゲートウェイ キャッシュに関連する知識の世界にアクセスできることを意味します。

Learn more