フラグメントキャッシングとは、Webページの一部分をキャッシュすることを指します。たとえば、ページに年間売上高のサマリーを表で表示する場合、この表をキャッシュに格納することで、各リクエストでこの表を生成するのに必要な時間を削減できます。フラグメントキャッシングは、データキャッシングを基盤として構築されています。
フラグメントキャッシングを使用するには、ビューで次の構成を使用します。
if ($this->beginCache($id)) {
// ... generate content here ...
$this->endCache();
}
つまり、コンテンツ生成ロジックを、beginCache()とendCache()の呼び出しのペアで囲みます。コンテンツがキャッシュにある場合、beginCache()はキャッシュされたコンテンツをレンダリングし、false
を返し、コンテンツ生成ロジックをスキップします。そうでない場合、コンテンツ生成ロジックが呼び出され、endCache()が呼び出されると、生成されたコンテンツがキャプチャされ、キャッシュに格納されます。
データキャッシングと同様に、コンテンツキャッシュを一意に識別するために、一意の$id
が必要です。
フラグメントキャッシングを削除するには、`php Yii::$app->cache->delete(['yii\widgets\FragmentCache', $id]);` を使用できます。
beginCache()メソッドの2番目のパラメーターとしてオプション配列を渡すことで、フラグメントキャッシングに関する追加のオプションを指定できます。内部的には、このオプション配列を使用して、実際のフラグメントキャッシング機能を実装するyii\widgets\FragmentCacheウィジェットが構成されます。
フラグメントキャッシングで最も一般的に使用されるオプションは、おそらくdurationです。これは、コンテンツがキャッシュ内で有効なままになる秒数を指定します。次のコードは、コンテンツフラグメントを最大1時間キャッシュします。
if ($this->beginCache($id, ['duration' => 3600])) {
// ... generate content here ...
$this->endCache();
}
オプションが設定されていない場合、デフォルト値の60が使用され、キャッシュされたコンテンツは60秒後に期限切れになります。
データキャッシングと同様に、キャッシュされるコンテンツフラグメントにも依存関係を持たせることができます。たとえば、表示される投稿のコンテンツは、投稿が変更されたかどうかによって異なります。
依存関係を指定するには、dependency オプションを設定します。このオプションには、yii\caching\Dependency オブジェクト、または依存関係オブジェクトを作成するための設定配列のいずれかを指定できます。次のコードは、フラグメントコンテンツがupdated_at
カラムの値の変更に依存することを指定しています。
$dependency = [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT MAX(updated_at) FROM post',
];
if ($this->beginCache($id, ['dependency' => $dependency])) {
// ... generate content here ...
$this->endCache();
}
キャッシュされるコンテンツは、いくつかのパラメータに応じて変化させることができます。たとえば、複数の言語をサポートするWebアプリケーションでは、同じビューコードで異なる言語のコンテンツを生成できます。したがって、キャッシュされたコンテンツを現在のアプリケーション言語に応じて変化させることができます。
キャッシュのバリエーションを指定するには、variations オプションを設定します。これは、それぞれ特定のバリエーション要因を表すスカラー値の配列である必要があります。たとえば、言語によってキャッシュされたコンテンツのバリエーションを作成するには、次のコードを使用します。
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) {
// ... generate content here ...
$this->endCache();
}
特定の条件が満たされた場合にのみフラグメントキャッシングを有効にしたい場合があります。たとえば、フォームを表示するページの場合、GETリクエストで最初に要求された場合にのみフォームをキャッシュします。フォームのその後の表示(POSTリクエストによる)は、フォームにユーザー入力が入力されている可能性があるため、キャッシュしないでください。これを行うには、次のようにenabledオプションを設定します。
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) {
// ... generate content here ...
$this->endCache();
}
フラグメントキャッシングはネストできます。つまり、キャッシュされたフラグメントを、これもキャッシュされている別のフラグメント内に含めることができます。たとえば、コメントは内部フラグメントキャッシュにキャッシュされ、投稿コンテンツと共に外部フラグメントキャッシュにキャッシュされます。次のコードは、2つのフラグメントキャッシュをネストする方法を示しています。
if ($this->beginCache($id1)) {
// ...content generation logic...
if ($this->beginCache($id2, $options2)) {
// ...content generation logic...
$this->endCache();
}
// ...content generation logic...
$this->endCache();
}
ネストされたキャッシュには、異なるキャッシングオプションを設定できます。たとえば、内部キャッシュと外部キャッシュでは、異なるキャッシュ期間値を使用できます。外部キャッシュにキャッシュされたデータが無効になっても、内部キャッシュは有効な内部フラグメントを提供する場合があります。ただし、その逆は当てはまりません。外部キャッシュが有効であると評価された場合、内部キャッシュのコンテンツが無効になった後でも、同じキャッシュされたコピーを引き続き提供します。したがって、ネストされたキャッシュの期間または依存関係の設定には注意する必要があります。そうでないと、古い内部フラグメントが外部フラグメントに残ってしまう可能性があります。
フラグメントキャッシングを使用する場合、コンテンツの大部分が比較的静的だが、1つまたは少数の場所を除いては静的ではないという状況に遭遇する可能性があります。たとえば、ページヘッダーには、メインメニューバーと現在のユーザーの名前が表示される場合があります。もう1つの問題は、キャッシュされるコンテンツに、各リクエストで実行する必要があるPHPコード(アセットバンドルの登録コードなど)が含まれている可能性があることです。どちらの問題も、いわゆる動的コンテンツ機能で解決できます。
動的コンテンツとは、フラグメントキャッシュ内に含まれていてもキャッシュされない出力フラグメントのことです。コンテンツを常に動的にするには、包含コンテンツがキャッシュから提供されている場合でも、各リクエストで何らかのPHPコードを実行して生成する必要があります。
キャッシュされたフラグメント内にyii\base\View::renderDynamic()を呼び出して、次のように目的の場所に動的コンテンツを挿入できます。
if ($this->beginCache($id1)) {
// ...content generation logic...
echo $this->renderDynamic('return Yii::$app->user->identity->name;');
// ...content generation logic...
$this->endCache();
}
renderDynamic()メソッドは、PHPコードをパラメータとして受け取ります。PHPコードの戻り値は、動的コンテンツとして扱われます。包含フラグメントがキャッシュから提供されているかどうかに関係なく、同じPHPコードが各リクエストで実行されます。
注:バージョン2.0.14以降、yii\base\DynamicContentAwareInterfaceインターフェースとそのyii\base\DynamicContentAwareTraitトレイトを介して動的コンテンツAPIが公開されています。例として、yii\widgets\FragmentCacheクラスを参照できます。
タイプミスを見つけたか、このページの改善が必要だと考えますか?
Githubで編集する !
コメントするにはサインアップまたはログインしてください。