.NET TIPS

[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?

山田 祥寛
2004/11/05

 ページ・アクセスのパフォーマンスを改善する施策として、よく用いられる手法の1つが「キャッシング」だ。キャッシングとは、ページ処理の過程で生成されたコンテンツをメモリなどの媒体に一時的にプールしておき再利用することで、2回目以降のページ・アクセスを高速化する仕組みをいう。

 もっとも、キャッシングと一口にいっても、そのアプローチはさまざまだ。例えば、ASP.NETには、大きく分けて、以下の表にある3つのキャッシング技術が用意されている。

名前 概要
ページ・キャッシュ ページ全体をキャッシュ
フラグメント・キャッシュ ページの断片(フラグメント)をキャッシュ
データ・キャッシュ ページの生成に利用されるデータセットなどのオブジェクトをキャッシュ
ASP.NETにおける3つのキャッシング技術

 本稿では、このうち「ページ・キャッシュ」について取り上げる。ページ・キャッシュは、比較的Web普及の早期から用いられてきたクラシカルなキャッシングの手法であるが、これまで動的なページでの活用にはあまり向いていないとされてきた。

 というのも、ASP.NETをはじめとする動的なページでは、フォームやクエリ情報などのリクエスト・データ(URL中に含まれるパラメータ)によって、出力されるコンテンツが変化するのが一般的だ。しかし、従来のページ・キャッシュの仕組みでは、あくまでURLの単位でコンテンツがキャッシュされるのが一般的であったため、リクエスト・パラメータが異なってしまうと、これを反映させることができなかったのだ。

 これでは、いくらコンテンツをキャッシュしたとしても、それがヒットする可能性が低すぎてキャッシュとしては使い物にならない。これまでは、ページ・キャッシュとは、事実上、静的なページのための仕組みであったといえる。

 その点、ASP.NETのページ・キャッシュは賢く改良されている。コンテンツをURLの単位ではなく、より細かなリクエスト・パラメータやヘッダ情報、ブラウザの種類の単位にキャッシュすることができるのだ(Dynamic Output Caching)。これによって、リクエスト・パラメータによってコンテンツの内容が変動する動的なページにおいても、ページ・キャッシュを利用することが可能になる。

 しかもASP.NETの便利な点は、ページ・キャッシュを利用するための特別なコーディングが一切不要であるという点だ。具体的な記述例を、以下に見てみよう。

<%@ Page ContentType="text/html" Language="C#" %>
<%@ OutputCache Duration="120" VaryByParam="id" %>
<script runat="Server">
void Page_Load(Object sender, EventArgs e) {
  lbl.Text=DateTime.Now.ToString();
}
</script>
<html>
<head>
<title></title>
</head>
<body>
最終更新日:<asp:Label id="lbl" runat="Server" />
</body>
</html>
ページ・キャッシュを行うための「.aspx」ファイル(C#:pageCache_cs.aspx)
 
<%@ Page ContentType="text/html" Language="VB" %>
<%@ OutputCache Duration="120" VaryByParam="id" %>
<script runat="Server">
Sub Page_Load(sender As Object, e As EventArgs)
  lbl.Text=DateTime.Now.ToString()
End Sub
</script>
<html>
<head>
<title>ページ・キャッシュ</title>
</head>
<body>
最終更新日:<asp:Label id="lbl" runat="Server" />
</body>
</html>
ページ・キャッシュを行うための「.aspx」ファイル(VB.NET:pageCache_vb.aspx)

 ページ・キャッシュを制御するのは、@OutputCacheディレクティブの役割だ。VaryByParam属性には、キャッシュを区別するためのキーとなるリクエスト・パラメータ名のリストを指定することができる。

 例えば上記のサンプルでは「id」という名前をキーとして指定しているので、パラメータ(クエリ情報)idの単位にキャッシュが生成されるというわけだ。もちろん、複数のパラメータで複合的にキャッシュを区別することも可能で、その場合は、VaryByParam属性に指定するパラメータ名をセミコロン(;)で区切ればよい。また、Duration属性はキャッシュの有効期限を秒単位で指定するためのものだ。ここでは2分(120秒)としておこう。この数字は、ページを生成する元データの更新頻度などに合わせて、適宜調整してほしい。

 それではさっそく、該当のWebフォーム・ページにアクセスして、キャッシュが有効になっている様子を確認してみよう。例えば、上のサンプル・ページに対して「http://localhost/netIns/pageCache_vb.aspx?id=12345」というURLでアクセスしてほしい。

初回アクセス時のサンプル・プログラムの実行結果

 次いで、120秒以内に、かつ、同一のURL(クエリ情報)でアクセスしてみよう。

2回目アクセス時のサンプル・プログラムの実行結果

初回アクセス時と最終更新日時が変わっておらず、メモリ上のキャッシュ・データが使われていることが確認できるはずだ。しかし、今度は、クエリ情報の異なるURL(例えば、「http://localhost/netIns/pageCache_vb.aspx?id=98765」)でアクセスしてみるとどうだろう。

クエリ情報を変更した場合のサンプル・プログラムの実行結果

 確かに、最終更新日時が変更されており、新たにページの生成処理が行われたことを確認できる。もちろん、この後、初回アクセスで利用したURLでアクセスすると(初回アクセスから120秒以内であれば)、再びキャッシュの内容を表示することができるはずだ。

 このように、ページ・キャッシュの仕組みはごく簡単に実装できるパフォーマンス改善の施策だ。最後に、@OutputCacheディレクティブで指定可能な主要属性をまとめておく(フラグメント・キャッシュにかかわる属性は除く)。

属性 概要
Duration キャッシュの有効期限(秒)
Location キャッシュ・データの格納先
設定値 格納先
Any クライアント、プロキシ・サーバ、アプリケーション・サーバのいずれか(既定)
Client クライアント
Downstream クライアント、またはプロキシ・サーバ
None キャッシングしない
Server アプリケーション・サーバに格納
ServerAndClient クライアント、または、アプリケーション・サーバ
VaryByCustom キャッシュ・データを切り替えるための任意のキー
VaryByHeader キャッシュ・データを切り替えるためのHTTPヘッダ名
VaryByParam キャッシュ・データを切り替えるためのリクエスト・パラメータ名(パラメータによる区別をしない場合は“none”、すべてのパラメータを切り替えのキーにしたい場合には“*”を指定することも可能)
@OutputCacheディレクティブの主な属性

 例えば、VaryByHeader属性に“Accept-Language”(ブラウザの対応言語)を指定することで対応言語の単位にキャッシュ・データを区分することができる。別稿「[ASP.NET]リソース・ファイル活用で国際化対応サイトを構築するには?」で紹介した国際化対応ページなどでは、言語ごとにコンテンツをキャッシュできるので、有効な手法となるだろう。

 また、VaryByCustom属性はキャッシュ・データを切り替えるための任意のキーワードを設定することができる。デフォルトでは“Browser”という値だけを設定することができ、その場合には、クライアント・ブラウザの単位にキャッシュを切り替えることが可能になる。そのほか、任意のキーワードを設定する方法については、「[ASP.NET]任意のキーによりページ・キャッシュを切り替えるには?」で詳述している。End of Article

カテゴリ:Webフォーム 処理対象:キャッシング
使用キーワード:@OutputCacheディレクティブ
関連TIPS:[ASP.NET]リソース・ファイル活用で国際化対応サイトを構築するには?
関連TIPS:[ASP.NET]任意のキーによりページ・キャッシュを切り替えるには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?
[ASP.NET]任意のキーによりページ・キャッシュを切り替えるには?
[ASP.NET]データセットをキャッシングするには?
[ASP.NET]データベース更新のタイミングでキャッシュを破棄するには?
[ASP.NET]サイト共通のキャッシュ・ポリシーを設定するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間