次の方法で共有


サービスを使用するアプリケーションのパフォーマンス上の考慮事項

更新 : 2007 年 11 月

このトピックでは、ASP.NET のメンバシップ、ロール、プロファイル プロパティ、セッション状態、Web パーツのパーソナル化、およびサイト ナビゲーションを使用する場合のパフォーマンスの最適化について説明します。

メンバシップ

このセクションでは、ASP.NET メンバシップの効率的な使用について説明します。

メンバシップ リストの効率的な収集

Membership クラスのメソッドを呼び出す場合、PageIndex メンバおよび PageSize メンバを取得するオーバーロードされたメソッドを呼び出します。これらのオーバーロードにより、実行速度が速くなります。結果データが、Web サーバーから送信されるデータより少なくなるからです。Membership クラスの GetAllUsers メソッドを例に取ります。GetAllUsers メソッドをパラメータを指定せずに呼び出すと、すべてのメンバシップ ユーザーが返されます。これに対して、GetAllUsers オーバーロードを呼び出すと、1 ページ分のユーザーのみが返されるので、ページで処理されるデータ量が減ります。

オンライン ユーザー数を取得した場合のキャッシュ結果

GetNumberOfUsersOnline メソッドを呼び出して、Web サイトでアクティブと見なされるユーザー数を表示できます。このメソッドは、メソッドが呼び出されるたびにメンバシップ テーブルの各行を検査するので、データベース内のユーザー数が多い場合、パフォーマンスがかなり低下する可能性があります。このメソッドは、必要な場合にのみ呼び出し、正確な数が必要でなければ、その値を一定期間キャッシュしておきます。

ロール

既定では、GetRolesForUser メソッドはページが読み込まれるたびに自動的に呼び出され、ユーザーが存在するロールを返します。ロールは RolePrincipal オブジェクト内の辞書に格納されます。Web ページが実行されている間、ロールの検査はこの辞書を使用して行われます。ページを読み込むたびにプロバイダにアクセスしないようにして、サーバー処理時間を削減するには、アプリケーションの Web.config ファイルの CacheRolesInCookie 属性を true に設定します。これにより、ユーザーのロールのリストは Cookie に格納されます。以降のページ読み込みでは、ロール情報はプロバイダの呼び出しを使用するのではなく、Cookie から読み込むことができます。

GetRolesForUser メソッド、IsInRole プロパティ、および GetRoles メソッドをコード内で使用して、ロールのメンバシップを検証できます。これらのメソッドのやり取りを理解することで、アプリケーションで実行する必要があるタスクにとって最も効率的なコードを記述できます。

GetRolesForUser メソッドは、常にプロバイダにアクセスします。IsInRole メソッドを呼び出すと、Cookie のキャッシュが有効でない場合、ページへの最初の要求で必ず GetRolesForUser メソッドが呼び出されます。Cookie のキャッシュが有効な場合、IsInRole メソッドを呼び出すと、代わりに Cookie にキャッシュされているロール情報が使用されます。GetRoles メソッドを最初に呼び出すと、Cookie キャッシュが有効でも無効でも、GetRolesForUser メソッドが呼び出されます。ただし、ページ上でのそれ以降の GetRoles メソッドの呼び出しでは、RolePrincipal 内にキャッシュされたロール情報が使用されます。

ms228100.alert_note(ja-jp,VS.90).gifメモ :

機密情報を Cookie に格納すると、その情報がユーザーに公開される可能性があります。最高のセキュリティを求める場合は、Cookie キャッシュを有効にしないでください。

プロファイル プロパティ

ページを読み込むときにコードがプロファイル プロパティにアクセスする場合、プロファイル プロバイダは、現在のユーザーのすべてのプロファイル プロパティを読み込みます (具体的には、プロバイダはそのプロファイル プロバイダに関連付けられているすべてのプロパティを読み込みます)。プロファイル プロパティの値が変更されている場合、ページのアンロード時に新しい情報がプロバイダのデータ ストアに書き戻されます。ASP.NET は、整数や文字列などの組み込みの型が変更されたかどうかは判断できますが、組み込みでない型が変更されたかどうかは判断できません。

プロファイル プロパティが保存されたかどうかを判断するアルゴリズムは、次のとおりです。

  • すべてのプロファイル プロパティの型が組み込みの型で、変更されていない場合、プロファイルはデータ ストアに書き込まれません。

  • すべてのプロファイル プロパティの型が組み込みの型で、何らかの変更が加えられている場合、すべてのプロパティ値がデータ ストアに書き込まれます。

  • プロパティが組み込みでない型の場合、ASP.NET は値が変更されているかどうかを判断できません。このプロパティがコード内でアクセスされると、プロパティ値はデータ ストアに書き込まれます。

    ms228100.alert_note(ja-jp,VS.90).gifメモ :

    すべての場合において、この判断は、対象のプロバイダのすべてのプロファイル プロパティに適用されます。

組み込みでないプロパティ型を使用している場合、各ページの終わりでプロファイル データを書き込む要求は時間を要します。このオーバーヘッドは以下の方法で軽減できます。

  • プロファイルでは組み込みの型のみを使用します。

  • <profile> 構成要素の automaticSaveEnabled 属性を Off に設定し、代わりに、変更を検出し必要なときにプロパティ値を保存するカスタム コードを記述します。

  • ProfileAutoSaving イベントを処理するカスタム コードを記述し、イベント コードでプロファイル プロパティに変更が行われたかどうかを判断します。プロパティが変更されていない場合、自動保存操作をキャンセルし、イベントの ContinueWithProfileAutoSave プロパティを false に設定します。

  • 詳細については個別のユーザーの Web サイトの作成 (Visual Studio).

セッション状態

アウトプロセス セッション状態モード (詳細については、「セッション状態モード」を参照) を使用する場合は、パフォーマンスについて考慮する必要があります。このセクションでは、セッション状態のパフォーマンスの最適化に関して説明します。

セッション状態の読み込みおよび書き込みオーバーヘッドの削減

既定では、セッション ステータス情報は各ページ読み込み中に読み込まれます。@ Page ディレクティブの EnableSessionState 属性によって、以下の設定でセッション状態の読み込みを制御できます。

  • True   セッション状態データは、各ページ読み込みで読み込まれ、変更されている場合は保存されます。ASP.NET は、整数や文字列のような組み込みの型が変更されたかどうかを判断できます。すべてのセッション状態値が組み込みの型で、変更されていない場合、セッションは保存されません。組み込みの型でない値があり、組み込みでないセッション値がアクセスされる場合、すべてのセッション ステータス情報が保存されます。これは、ASP.NET が組み込みでない型については変更されたかどうかを追跡せず、確実な選択としてすべてのデータを保存するからです。

  • False   セッション状態は、ページが読み込まれるときに読み込まれません。

  • ReadOnly   セッション状態は、各ページ読み込みで読み込まれますが、コード内でセッション状態値に対する変更が行われても保存されません。

セッション状態のロックの競合の回避

セッション状態を必要とする <IFRAME> 要素をページ上で使用しないでください。同じセッション状態 ID を持つ ASP.NET に対して複数の要求が行われ、その要求がすべて EnableSessionState が true に設定されている ASP.NET ページに対するものである場合、並行要求はアウトプロセス セッション状態に関連付けられるロックを取得するために互いに競合します。<IFRAME> 要素の場合、1 つのページに複数の <IFRAME> 要素が表示される ASP.NET ページが同じセッション データを求めて競合する可能性があることを意味します。その結果、各個別要求がサーバー上でシリアル化されます。

Web パーツのパーソナル化

ページが実行されると、ASP.NET のパーソナル化情報が読み込まれます。Web パーツのパーソナル化情報が変更されているかどうかを判断するために、ASP.NET は Equals メソッドを呼び出し、PersonalizableAttribute 属性で指定されるプロパティの新旧の値を比較します。

パーソナル化プロパティ値が変更されている場合、パーソナル化データは保存されます。整数などの組み込みの型については、Equals メソッドが新旧のプロパティ値を直接比較します。ただし、組み込みでない型については、ASP.NET は参照の値を比較しますが、データは型インスタンスによって必ずしも維持されるわけではありません。

たとえば、ArrayList 型のプロパティで、Equals メソッドは ArrayList 参照の新旧の値は比較しますが、ArrayList オブジェクトの内容は比較しません。Equals メソッドは、ArrayList 参照が変更されていない場合、新しい項目がリストに追加されていても、true を返します。その場合、ArrayList データは保存されません。

このような組み込みでない型に対するアルゴリズムは効率的ですが、データを保存しないようにするあまり失敗する場合もあります。ArrayList オブジェクトなどの組み込みでない型のデータを保存する場合は、コントロールが WebPart から派生しているなら IsDirty プロパティを true に設定します。そうでない場合は、コントロールをパラメータとして処理する SetPersonalizationDirty メソッドを呼び出します。

サイト ナビゲーション

大きなサイト マップでは、小さいサイト マップに比べてパフォーマンスが低下します。たとえば、ノードの数を 100 から 1000 まで 10 倍ずつ増やすテスト シナリオでは、ページ読み込み時間は約 3 分の 1 ずつ増加します。

ロールに基づいてノードにフィルタをかけるセキュリティ トリミングでは、ノード数を増やすよりもはるかにパフォーマンスが低下します。たとえば、1000 のノードを持つサイト マップには、100 のノードを持つサイト マップの 10 倍の処理オーバーヘッドがかかります。

この影響を軽減するための推奨事項は次のとおりです。

  • セキュリティ トリミングがオンの場合、推奨されるノードの最大数は 150 です。

  • サイト マップの各ノードに Roles 属性を設定します。このロール属性が存在すると、ユーザーが SiteMapNode 属性に指定されているロールの 1 つに属している場合、ASP.NET はこの属性に関連付けられている URL と URL のファイル承認をバイパスできます。ただし、ユーザーが指定されているロールのいずれにも属していない場合、ASP.NET のファイル処理は低速に戻り、URL 承認を確認します。

  • SiteMapProvider クラスを継承するクラスを作成し、IsAccessibleToUser メソッドをオーバーライドして、サイト マップの各ノードの Roles 属性のみを確認します。これにより、URL とファイル承認がバイパスされるので、フィルタ処理の速度が上がります。ただし、この方法では Web アプリケーションに 2 つの並行するセキュリティ定義が必要です。1 つは、Web.config ファイルの承認情報 (および、Windows 認証が有効な場合は、ファイル承認用の NTFS アクセス制御リスト) です。もう 1 つは、サイト マップ内のロール情報です。サイト マップ処理でのパフォーマンス向上よりも、セキュリティ情報を分割することによるセキュリティ管理のオーバーヘッドを重視する必要があります。

詳細については、「ASP.NET のサイト マップ セキュリティ トリミング」および「ASP.NET の承認」を参照してください。

参照

概念

ASP.NET のサイト ナビゲーションの保護

ASP.NET セッション状態の概要