AEM アーキテクチャ内のキャッシュの最適化は、パフォーマンスを大幅に向上させるための一番手っ取り早い方法の 1 つです。 この記事では、AEM アーキテクチャ内で使用可能な様々なキャッシュを最適化する方法について説明することに重点を置きます。
すべての AEM アーキテクチャで、ユーザーがサイトを訪問すると複数のキャッシュのレイヤーが発生します。 標準の AEM アーキテクチャで考慮すべき4つのキャッシュのレイヤーがあります。 これには、Web ブラウザー、CDN、ディスパッチャーおよび AEM インスタンスが含まれます。

ユーザーがサイトの繰り返し訪問を行ったときのキャッシュの最初のレベルは、独自のブラウザです。 ブラウザのレベルのキャッシングは、Cache-Control: max-age=... 応答ヘッダーを介して、通常実行されます。 max-age の設定は、「再検証」する前にまたはサイトから再リクエストする前にファイルをキャッシュするか、またはサイトから再要求するか、ブラウザに指示します。 max-age のキャッシュのこのコンセプトは、通常「キャッシュの有効期限」または TTL(「Time to Live」)と呼ばれます。
キャッシュの実行方法が影響するキャッシュ-制御ヘッダー内に様々なオプション(または「ディレクティブ」)があります。 一般的なディレクティブは、次のとおりです。
- プライベート - キャッシュ-制御ヘッダーのプライベートディレクティブでは、CDN などの中間のキャッシュではなく、ブラウザでキャッシュされるファイルのみが格納されます。 このディレクティブの実際の用途は、ページにパーソライズされた/ユーザー固有のコンテンツが含まれている場合です。
使用例:
キャッシュ-制御:max-age=300, private - s-maxage-キャッシュ制御ヘッダーの s-maxage ディレクティブで、CDN などの共有キャッシュに別の TTL を設定することができます。 この値が設定されている場合、ブラウザーは max-age に設定されているものを使用し、他のキャッシュは、代わりに s-maxage 設定を尊重します。
使用例:
キャッシュ制御:max-age=600、s-maxage=300
最新のブラウザーは全て Cache-Control ヘッダーをサポートしています。しかし、古い廃止されたヘッダーは依然キャッシュに影響を与える HTTP/1.0 から存在することがあります。 これらのヘッダーは Expires と Pragma です。 非常に古いブラウザーをサポートする必要がない場合は、これらのレスポンスヘッダーを送信しないでください。
キャッシュに加えて、再検証も重要な概念です。 再検証は Last-Modified (response) / If-Modified-Since (request) ヘッダーおよび ETag (response) / If-None-Match (request) ヘッダーに依存します。
警告:
ブラウザーのテスト:
Google Chrome でキャッシュをテストする際、https でテストを行い、自己署名証明書がある場合、何もキャッシュされません。 Chrome は信頼できないまたは無効な証明書が存在すると、応答をキャッシュしないまたは再検証を実行しません。
ディスパッチャーの注意:
AEM ディスパッチャー v4.2.3 およびそれ以前のバージョンでは、/enableTTL が max-age ディレクティブを使用してのみキャッシュするという問題があります。 これは、private または s-maxage ディレクティブが設定されていても、max-age が設定されていればキャッシュすることを意味します。 この問題は、ディスパッチャー 4.2.4 以降のバージョンで解決されています。
CDN または「コンテンツ配信ネットワーク」は、ユーザーに最も近い場所からコンテンツをキャッシュして配信するように設計された Web サーバーの分散ネットワークです。 これにより、ネットワークのホップ数やユーザーのコンピューターからコンテンツまでの距離を短縮し、「ラウンドトリップタイム」(RTT)を短縮します。 RTT は、ブラウザがサイトにリクエストを送信して応答を受信するまでの時間です。 CDN プロバイダースペースの競争は、CDN のコスト効率を大幅に向上させました。 これにより、サイトに CDN を使用することを簡単に決められるようになります。 まだ CDN を使用していない場合、サイトに CDN を組み込む必要があります。
多くの CDN プロバイダーがあり、それぞれが異なる機能と設定を提供しています。
CDN キャッシュの仕組み
CDN は、ブラウザーに類似するルールに従ってコンテンツをキャッシュします。 これらはキャッシュ制御 HTTP 応答ヘッダーに依存し、キャッシュ制御ヘッダーが存在しない場合、通常は有効期限ヘッダーに戻ります。
ほとんどの CDN は、キャッシュを手動でフラッシュする方法をいくつか提供しています。 多くの場合、キャッシュのフラッシュは、ファイルを持つすべてのエッジサーバーに伝達する際、多少の遅延(例えば 15 分)があります。
CDN の使用状況を最適化する
CDN でファイルを最適にキャッシュしていることを確認するため、いくつかやることがあります。
- キャッシュ制御ヘッダーで、stale-while-revalidate と stale-if-error ディレクティブをサポートする CDN を使用してください。
- stale-while-revalidate ー このディレクティブは、キャッシュファイルが期限切れになった後、新しいファイルを取得する間に、CDN にファイルの古い(キャッシュ済み)バージョンを提供するよう指示します。
- stale-if-error ー 同様に、このディレクティブは、再検証中に原点がエラーを返す場合、CDN にファイルの古い(キャッシュ済み)バージョンを提供するよう指示します。
- GZip は、事前圧縮されていないすべてのファイルタイプの応答を圧縮します。
- これは、ディスパッチャーレベルから行う必要があります。 これにより、CDN に送信されるバイト数を減らすことができます。 CDN は通常、転送されたバイト数で請求するため、応答を圧縮することでコストが軽減されます。
- ディスパッチャーレベルで GZip 圧縮を有効にする。
- Apache ー mod_deflate を使用します。 Vary で mod_deflate を使用する際、注意してください。 場合によっては、Vary ヘッダーにより、CDN とブラウザーがキャッシュを完全にスキップすることがあります。
- Microsoft IIS ー 動的圧縮を使用します。
- 大きなファイルや既に圧縮されているファイルの gzip 圧縮は使用できません。 ほとんどの画像形式とビデオ形式は既に圧縮されています。 Web サーバーレベルでその場で圧縮すると、パフォーマンスに対するコストが非常に高くなります。
- Apache では、AddOutputFilterByType ディレクティブを使用して(
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript)を使用してこれを実行できます。 - IIS では、<dynamicTypes> 設定で制御できます。
- Apache では、AddOutputFilterByType ディレクティブを使用して(
- CDN プロバイダーが Edge-side Includes(ESI)をサポートしている場合は、この機能を活用してください。
- AEM コンポーネントは、ESI を使用して分割できます。 これを行うには、Apache Sling Dynamic Includes を使用するか、カスタムソリューションを実装します。
- これは、静的なページがあり、ページの一部でより動的なコンテンツを提供している場合に便利です。 このような場合、基本的にページを複数の CDN ファイルに分割しています。 これにより、異なる時間にページの異なる部分をキャッシュできます。
一般的な CDN プロバイダー
一般的な CDN プロバイダーの一覧を次に示します。
- Microsoft Azure CDN
- Amazon Cloudfront
- Akamai
- Google Cloud CDN
- Rackspace CDN
- Max CDN
- Cloudflare
- Fastly
- F5 Networks CDN
- さらに多くがあり、それぞれに異なる機能があります。
警告:
Vary 応答ヘッダーには注意してください。 場合によっては、Vary により、CDN とブラウザーがキャッシュを完全にスキップすることがあります。 一般的な経験則として、Vary: Accept-Encoding(応答が gzip 圧縮されている場合のみ適用)を除き、Vary を追加しないでください。 つまり、応答の出力を「Vary」する必要がある場合は、別の URL を使用してください。
例えば、モバイルとデスクトップ用の異なるバージョンの HTML がある場合は、別の URL を使用します。 これにより、CDN とブラウザーのキャッシュがより効率的になります。
CDN キャッシュの有効期限が切れている場合、リクエストは AEM ディスパッチャーキャッシュに到達します。 このレベルでは、キャッシュを最適化するために多くのことを実行できます。
これは大きなトピックなので、ディスパッチャーキャッシュを最適化する方法の詳細については、この記事を参照してください。
- デフォルトで AEM が設定していない次の HTTP 応答ヘッダーを設定します。
- Cache-Control: max-age =… - このヘッダーを設定するためには、共通 ACS - ディスパッチャー TTL を使用、またはそれを設定するカスタムコードを実装できます。
- 最後の変更 - ページコンテンツが、記事などの比較的静的だった場合、最後に変更されたヘッダーを cq:lastModified 日時へを設定できます(最後の記事は変更されています)。 ただし、ページがコンポーネントのコンテンツに含まれている JCR クエリー結果をもつダイナミックの場合、現在の日付/時刻を使用するように設定することをお勧めします。
- ETag - 最後の変更の代わりにこれを使用する場合は、ページのアクティベーションを聞き、ページコンテンツの md5 を生成する ReplicationEventListener を書くことができます。 これは、作成者インスタンスのページの jcr:content ノードのプロパティとして設定できます。 ページがレプリケートされると、公開インスタンスに送信されます。 比較的静的なコンテンツを含むページコンポーネントの場合は、うまく作動する可能性があります。ただし、ページがダイナックまたは多くのコンテンツを参照している場合は、ETag を省略(または計算)する必要があります。
- サイトにパーソナライズされた/ダイナミックコンテンツがある場合:
- Apache Sling ダイナミックを使用して、コンテンツを分割するために含まれており、ページの異なる一定部分が、異なる一定の時間でキャッシュします。
- キャッシングは、次のように実行できます。
- エッジサイドが CDN に(ESI)を含める
- サーバーサイドが Web サーバーに(SSI)を含める
- または、ブラウザー上の非同期 JavaScript および XML(AJAX)
- ページ上のコンポーネントは個別のリクエストに分割でき、異なる期間にキャッシュできます。 比較的静的な一部のページは、より長い期間でキャッシュできます。
- キャッシングは、次のように実行できます。
- ACS に共通する HTTP キャッシュ機能の使用を検討してください。
- Apache Sling ダイナミックを使用して、コンテンツを分割するために含まれており、ページの異なる一定部分が、異なる一定の時間でキャッシュします。
- クライアントライブラリの最適化。
- クライアントライブラリの縮小を有効にします。
- クライアントライブラリ内のファイルが事前に縮小されている場合は、そのクライアントライブラリで縮小を無効にします。 cq:ClientLibraryFolder ノードを編集します。
- String[] 型の jsProcessor プロパティを 「min:none」に、
- String[] 型の cssProcessor プロパティも 「min:none」に設定します。
- 詳細は、こちらをご覧ください。
- ライブラリクライアントを埋め込み js および CSS ファイルを縮小します。
- ACS Commons の versioned-clientlibs を実装して、CDN とディスパッチャーがより長い期間 js ファイルと css ファイルをキャッシュできるようにします。