ASP.NET を使用して Web アプリケーションを作成するのは驚くほど簡単です。この単純さのため、多くの開発者は、パフォーマンスを向上させるためにアプリケーションを構築することに時間を費やしません。この記事では、高パフォーマンスの Web アプリケーションを作成するための 10 のヒントを紹介します。ただし、これらのアプリケーションは Web アプリケーションの一部にすぎないため、これらの提案を ASP.NET アプリケーションに限定するつもりはありません。この記事は、Web アプリケーションのパフォーマンス チューニングに関する決定的なガイドを目的としたものではありません。この主題を 1 冊の本で簡単にカバーすることはできません。この記事は優れた出発点であると考えてください。
仕事中毒になる前は、ロッククライミングを楽しんでいた。大きな登山をする前に、ガイドブックのルートを注意深く調べ、以前の訪問者からの推奨事項を読むことから始めます。しかし、ガイドがどれほど優れていても、特に難しい登山に挑戦する前に、実際のロック クライミングの経験が必要です。同様に、パフォーマンスの問題を解決したり、高スループットのサイトを実行したりする必要がある場合にのみ、高パフォーマンスの Web アプリケーションの作成方法を学ぶことができます。
私の個人的な経験は、マイクロソフトの ASP.NET 部門でインフラストラクチャ プログラム マネージャーとして働いたことに由来します。そこでは、 www.ASP.NETを実行および管理し、いくつかの有名なサーバーの 1 つであるコミュニティ サーバーの設計を支援しました。
ASP.NET アプリケーション (ASP.NET フォーラム、.Text、nGallery を 1 つのプラットフォームに統合)。私が助けたヒントのいくつかはあなたにも役立つと確信しています。
アプリケーションを複数の論理層に分割することを検討する必要があります。 3 層 (または n 層) 物理アーキテクチャという用語を聞いたことがあるかもしれません。これらは通常、プロセスやハードウェア間の機能を物理的に分離する規定のアーキテクチャ アプローチです。システムを拡張する必要がある場合、ハードウェアを簡単に追加できます。ただし、プロセスやマシンのジャンプに関連してパフォーマンスが低下するため、回避する必要があります。したがって、可能であれば、ASP.NET ページとその関連コンポーネントを同じアプリケーション内で一緒に実行するようにしてください。
コードの分離とレイヤー間の境界により、Web サービスまたはリモート処理を使用するとパフォーマンスが 20% 以上低下します。
データ層は少し異なります。通常、データベース専用のハードウェアを使用する方が良いためです。ただし、データベースにジャンプするプロセスのコストは依然として高いため、コードを最適化する際にはデータ層のパフォーマンスを最初に考慮する必要があります。
アプリケーションのパフォーマンスの修正に入る前に、まずアプリケーションのプロファイリングを行って、特定の問題を特定してください。ガベージ コレクションの実行に必要な時間の割合を表すキー パフォーマンス カウンターなど、主要なパフォーマンス カウンターは、アプリケーションが主にどこに時間を費やしているかを調べるのにも役立ちます。ただし、どこに時間が費やされるかは、多くの場合非常に直感的ではありません。
この記事では、2 種類のパフォーマンスの向上について説明します。1 つは大規模な最適化 (ASP.NET キャッシュの使用など)、もう 1 つは反復的な小規模な最適化です。こうした小さな最適化は、場合によっては特に興味深いものになります。コードに小さな変更を加えるだけで、大幅な時間が得られます。大規模な最適化を行うと、全体的なパフォーマンスが大幅に向上する場合があります。小規模な最適化では、特定のリクエストに対して数ミリ秒しか節約できない可能性がありますが、毎日すべてのリクエストを合計すると、大幅な改善となる可能性があります。
データ層のパフォーマンス
アプリケーションのパフォーマンスのチューニングに関しては、作業の優先順位を決めるために使用できるディップスティック テストがあります。コードはデータベースにアクセスしていますか?もしそうなら、どのくらいの周波数でしょうか?この同じテストは Web サービスやリモート処理を使用するコードにも適用できますが、この記事ではこれらについては説明しません。
特定のコード パスでデータベース リクエストが必要で、最初に他の領域 (文字列操作など) を最適化する必要があると考えられる場合は、このディップスティック テストを停止してから実行してください。パフォーマンスの問題が深刻でない場合は、データベースに関連する所要時間、返されるデータの量、およびデータベースとの往復の頻度を最適化することに時間を費やすことをお勧めします。
この一般的な情報を念頭に置いて、アプリケーションのパフォーマンスを向上させるのに役立つ 10 のヒントを見てみましょう。まず、最も大きな違いを生む可能性のある変更について説明します。
ヒント 1 — 複数の結果セットを返す
データベース コードを注意深く調べて、データベースへのリクエスト パスが複数存在するかどうかを確認してください。このような往復ごとに、アプリケーションが処理できる 1 秒あたりのリクエストの数が減少します。 1 つのデータベース要求で複数の結果セットを返すことにより、データベースとの通信に必要な全体的な時間を節約できます。同時に、リクエストを管理する際のデータベース サーバーの作業が軽減され、システムの拡張性も向上します。
動的 SQL を使用して複数の結果セットを返すこともできますが、私が推奨する方法はストアド プロシージャを使用することです。ビジネス ロジックをストアド プロシージャ内に置くべきかどうかについては議論がありますが、ストアド プロシージャ内のロジックで返されるデータを制限できる (データ セットのサイズを削減し、データ セットに費やす時間を短縮できる) 方が良いと思います。ネットワーク、ロジック層(データ)をふるい分ける必要がないため、これを優先する必要があります。
SqlCommand インスタンスとその ExecuteReader メソッドを使用して厳密に型指定されたビジネス クラスにデータを設定する場合、NextResult を呼び出すことで結果セット ポインターを前方に移動できます。図 1 は、型クラスを使用して複数の ArrayList を設定するサンプル セッションを示しています。データベースから必要なデータのみを返すと、サーバー上のメモリ割り当てがさらに削減されます。
図 1 DataReader からの複数の結果セットの抽出
// 最初の結果セットを読み取ります
Reader = command.ExecuteReader();
// その結果セットからデータを読み取ります。
while (reader.Read()) {
suppliers.Add(PopulateSupplierFromIDataReader(reader));
}
// 次の結果セットを読み取ります
Reader.NextResult();
// 2 番目の結果セットからデータを読み取ります。
while (reader.Read()) {
products.Add(PopulateProductFromIDataReader( リーダー ));
ヒント
2 - ページ分割されたデータ アクセス
ASP.NET DataGrid には、データ ページ分割のサポートという優れた機能があります。 DataGrid でページングが有効になっている場合、一度に固定数のレコードが表示されます。さらに、レコード間のナビゲーションを容易にするために、DataGrid の下部にページング UI が表示されます。ページング UI を使用すると、表示されたデータ内を前後に移動し、一度に固定数のレコードを表示できます。
小さなひねりもあります。 DataGrid を使用したページネーションでは、すべてのデータがグリッドにバインドされている必要があります。たとえば、データ レイヤーがすべてのデータを返す必要がある場合、DataGrid は現在のページに基づいて表示されるすべてのレコードをフィルターします。 DataGrid のページング時に 100,000 レコードが返された場合、リクエストごとに 99,975 レコードが破棄されます (ページ サイズが 25 レコードであると仮定)。レコード数が増加すると、各リクエストでより多くのデータを送信する必要があるため、アプリケーションのパフォーマンスが低下します。
よりパフォーマンスの高いページネーション コードを作成する優れた方法は、ストアド プロシージャを使用することです。図 2 は、Northwind データベースの Orders テーブルをページングするストアド プロシージャの例を示しています。つまり、この時点で必要なのは、ページ インデックスとページ サイズを渡すことだけです。その後、適切な結果セットが計算されて返されます。
図 2 注文テーブルのページング
プロシージャの作成northwind_OrdersPages
(
@PageIndex int、
@PageSize int
)
として
始める
@PageLowerBound int を宣言します
@PageUpperBound int を宣言します
DECLARE @RowsToReturn int
-- 最初に行数を設定します
SET @RowsToReturn = @PageSize * (@PageIndex + 1)
SET ROWCOUNT @RowsToReturn
-- ページ境界を設定します
SET @PageLowerBound = @PageSize * @PageIndex
SET @PageUpperBound = @PageLowerBound + @PageSize + 1
-- 選択結果を保存する一時テーブルを作成します
テーブル #PageIndex を作成する
(
IndexId int IDENTITY (1, 1) NOT NULL、
オーダーID int
)
-- 一時テーブルに挿入します。
#PageIndex (OrderID) に挿入
選択
注文ID
から
注文
注文方法
OrderID DESC
-- 合計数を返す
SELECT COUNT(OrderID) FROM Orders
-- ページングされた結果を返す
選択
O.*
から
命令O、
#PageIndex ページインデックス
どこ
O.OrderID = PageIndex.OrderID AND
PageIndex.IndexID > @PageLowerBound かつ
PageIndex.IndexID < @PageUpperBound
注文方法
PageIndex.IndexID
END
コミュニティ サーバーで、すべてのデータ ページングを完了するページング サーバー コントロールを作成しました。ご覧のとおり、ヒント 1 で説明した概念を使用して、ストアド プロシージャから 2 つの結果セット (レコードの総数と要求されたデータ) を返します。
返されるレコードの合計数は、実行されたクエリによって異なる場合があります。たとえば、WHERE 句を使用して、返されるデータを制限できます。ページ分割された UI に表示される合計ページ数を計算するには、返されるレコードの合計数を知っている必要があります。たとえば、合計 1,000,000 件のレコードがあり、WHERE 句を使用して 1,000 件のレコードに絞り込みたい場合、ページング UI を正しく表示するには、ページング ロジックがレコードの合計数を認識している必要があります。
ヒント 3 — 接続プーリング
Web アプリケーションと SQL Server 間の TCP 接続のセットアップは、非常にリソースを大量に消費する操作となる場合があります。 Microsoft の開発者は、以前から接続プーリングを使用できるようになり、データベース接続を再利用できるようになりました。リクエストごとに新しい TCP 接続を設定するのではなく、接続プールに接続がない場合にのみ新しい接続を設定します。接続が閉じられると、TCP 接続を完全に破棄するのではなく、接続プールに戻り、データベースへの接続が維持されます。
もちろん、接続に漏れが生じた場合には注意が必要です。接続の使用が終了したら、必ず接続を閉じてください。繰り返します: Microsoft® .NET Framework のガベージ コレクションについて誰が何と言おうと、接続の使用が終了したら、接続上で必ず Close または Dispose を明示的に呼び出してください。共通言語ランタイム (CLR) があらかじめ決められた時間に接続をクリアして閉じることを信頼しないでください。 CLR は最終的にクラスを破棄し、接続を強制的に閉じますが、オブジェクトのガベージ コレクションが実際にいつ発生するかは保証されません。
接続プーリングを最適な方法で使用するには、従う必要のあるルールがいくつかあります。まず接続を開いて操作を実行し、次に接続を閉じます。必要に応じて、リクエストごとに接続を複数回開いたり閉じたりします (できればヒント 1 を適用します)。ただし、接続を常に開いたままにしておくのではなく、さまざまなメソッドを使用して接続を渡したり渡したりします。次に、同じ接続文字列 (統合認証を使用している場合は同じスレッド ID) を使用します。同じ接続文字列を使用しない場合 (ログインしているユーザーに基づいて接続文字列をカスタマイズする場合など)、接続プールが提供するのと同じ最適化値は得られません。統合認証を使用し、多数のユーザーになりすます場合、接続プールの効率も大幅に低下します。 .NET CLR データ パフォーマンス カウンターは、接続プーリングに関連するパフォーマンスの問題を追跡するときに役立ちます。
アプリケーションが別のプロセスで実行されているデータベースなどのリソースに接続するときは常に、そのリソースへの接続にかかる時間、データの送信または取得にかかる時間、ラウンドトリップ数に焦点を当てて最適化する必要があります。アプリケーション内のあらゆる種類のプロセス ホッピングを最適化することが、パフォーマンスを向上させるための最初のポイントです。
アプリケーション層には、データ層に接続し、データを意味のあるクラス インスタンスとビジネス プロセスに変換するロジックが含まれています。たとえば、フォーラムまたはスレッド コレクションを設定するコミュニティ サーバーでは、ビジネス ルール (アクセス許可など) を適用し、最も重要なことに、そこでキャッシュ ロジックを実行します。
ヒント 4 — ASP.NET キャッシュ API
アプリケーション コードの行を記述する前に、最初に行うことの 1 つは、ASP.NET のキャッシュ機能を最大限に活用できるようにアプリケーション層を構造化することです。
コンポーネントを ASP.NET アプリケーションで実行する場合は、アプリケーション プロジェクトに System.Web.dll への参照を含めるだけで済みます。キャッシュにアクセスする必要がある場合は、HttpRuntime.Cache プロパティを使用します (このオブジェクトは Page.Cache および HttpContext.Cache からもアクセスできます)。
データのキャッシュにはいくつかのルールがあります。まず、データが複数回使用される可能性がある場合、これはキャッシュの使用に代わる良い方法です。次に、データが汎用的で、特定のリクエストやユーザーに固有ではない場合、これもキャッシュの候補として適しています。データがユーザーまたはリクエストに固有であるものの、存続期間が長い場合は、引き続きキャッシュできますが、これはあまり頻繁には使用されない可能性があります。 3 番目に、見落とされがちなルールは、キャッシュが多すぎる場合があるということです。通常、x86 コンピューターでは、メモリ不足エラーの可能性を減らすために、800 MB を超えないプライベート バイトでプロセスを実行する必要があります。したがって、キャッシュには制限を設ける必要があります。つまり、計算の結果を再利用できるかもしれませんが、その計算に 10 個のパラメーターが必要な場合、10 個の置換をキャッシュしようとすることになり、問題が発生する可能性があります。 ASP.NET サポートに対する最も一般的な要求の 1 つは、特に大規模なデータ セットの過剰なキャッシュによって引き起こされるメモリ不足エラーです。
キャッシュには、知っておく必要がある優れた機能がいくつかあります。まず、キャッシュには最も最近使用されていないアルゴリズムが実装されており、メモリの実行効率が低下した場合に、ASP.NET がキャッシュを強制的に消去 (未使用の項目をキャッシュから自動的に削除) できるようになります。次に、キャッシュは、強制的に期限切れにできる期限切れの依存関係をサポートします。これらの依存関係には、時間、キー、ファイルが含まれます。時間はよく使用されますが、ASP.NET 2.0 では、データベース キャッシュの無効化という、より強力な新しい無効化タイプが導入されています。データベース内のデータが変更されたときに、キャッシュ内の項目を自動的に削除することを指します。データベース キャッシュの無効化の詳細については、2004 年 7 月の MSDN マガジンの「Dino Esposito Cutting Edge」コラムを参照してください。キャッシュのアーキテクチャを理解するには、以下の図を参照してください。
ヒント 6 — バックグラウンド処理
コードへのパスはできるだけ高速である必要があります。リクエストごとに実行されるタスク、またはリクエスト n 回に 1 回実行されるタスクに多くのリソースが必要であると感じる場合があります。電子メールの送信や受信データの分析と検証はその一例です。
ASP.NET フォーラム 1.0 を分析し、コミュニティ サーバーを構成するコンテンツを再構築したところ、新しい投稿コード パスの追加が非常に遅いことがわかりました。新しい投稿が追加されるたびに、アプリケーションはまず重複した投稿がないことを確認する必要があります。次に、「悪い言葉」フィルターを使用して投稿を分析し、投稿された文字の絵文字を分析し、投稿にタグ付けしてインデックスを付け、要求されたら投稿する 適切なキューに移動し、添付ファイルを検証し、最終的に投稿したら、すぐにすべての購読者に電子メール通知を送信します。明らかに、多くのことが関係しています。
調査の結果、ロジックのインデックス作成と電子メールの送信にほとんどの時間が費やされていることがわかりました。投稿のインデックス作成は非常に時間のかかる操作であり、組み込みの System.Web.Mail 機能が SMYP サーバーに接続し、継続的に電子メールを送信することが判明しました。特定の投稿またはトピック領域の購読者の数が増加するにつれて、AddPost 関数の実行にかかる時間がますます長くなります。
電子メールのインデックス作成は、すべてのリクエストに必要なわけではありません。理想的には、この操作をバッチ処理して、一度に 25 件の投稿のインデックスを作成するか、すべての電子メールを 5 分ごとに送信したいと考えています。私たちは、最終的に Visual Studio® 2005 で使用されたデータ キャッシュ無効化のプロトタイプを作成するために以前に使用したコードを使用することにしました。
System.Threading 名前空間の Timer クラスは非常に便利ですが、.NET Framework では、少なくとも Web 開発者の間ではあまり知られていません。この Timer クラスは作成されると、ThreadPool 内のスレッドに対して構成可能な間隔で指定されたコールバックを呼び出します。これは、ASP.NET アプリケーションへのリクエストを受信せずにコードを実行するように設定できることを意味し、バックグラウンド処理に最適です。このバックグラウンド プロセスでは、インデックス作成や電子メールの送信などの操作を実行することもできます。
ただし、このテクノロジーにはいくつかの問題があります。アプリケーション ドメインがアンインストールされると、このタイマー インスタンスはイベントの発生を停止します。また、CLR にはプロセスごとのスレッド数に関する厳密な基準があるため、サーバーの負荷が高く、タイマーが完了するスレッドがない状況が発生し、ある程度の遅延が発生する可能性があります。 ASP.NET は、プロセス内で使用可能なスレッドを一定数維持し、要求処理に合計スレッドの一部のみを使用することで、この問題が発生する可能性を最小限に抑えようとします。ただし、非同期操作が多い場合には、これが問題になる可能性があります。
このコードをここに置くのに十分なスペースはありませんが、www.rob-howard.net から読みやすい例をダウンロードできます。 Blackbelt TechEd 2004 プレゼンテーションのスライドとデモをチェックしてください。
ヒント 7 — ページ出力キャッシュとプロキシ サーバー
ASP.NET はプレゼンテーション層 (またはプレゼンテーション層でなければなりません) であり、ページ、ユーザー コントロール、サーバー コントロール (HttpHandlers および HttpModules)、およびそれらが生成するコンテンツで構成されます。出力 (HTML、XML、画像、その他のデータ) を生成する ASP.NET ページがあり、すべての要求でこのコードを実行すると同じ出力が生成される場合、次の目的で使用できるツールがあります。ページ出力キャッシュの優れた代替手段です。
このコンテンツ行をページの先頭に追加します。<%@ Page OutputCache VaryByParams="none" Duration="60" %>
このページの出力を 1 回効率的に生成し、最大 60 秒間複数回再利用できます。その時点でページが再実行され、出力が ASP.NET キャッシュに再度追加されます。この動作は、いくつかの低レベルのプログラム API を使用して実現することもできます。出力キャッシュには、先ほど述べた VaryByParams プロパティなど、構成可能な設定がいくつかあります。 VaryByParams は要求されただけですが、HTTP GET または HTTP POST パラメータを指定してキャッシュ エントリを変更することもできます。たとえば、default.aspx?Report=1 またはdefault.aspx?Report=2 の出力をキャッシュするには、VaryByParam="Report" を設定するだけです。セミコロンで区切られたリストを指定することで、追加のパラメーターを指定できます。
多くの人は、出力キャッシュが使用されると、ASP.NET ページが、Microsoft Internet Security and Acceleration Server や Akamai で使用されるような、キャッシュ サーバーの下流に配置されるいくつかの HTTP ヘッダーも生成することを知りません。 HTTP キャッシュ ヘッダーを設定すると、ドキュメントをこれらのネットワーク リソースにキャッシュできるようになり、オリジン サーバーに返さずにクライアントの要求を満たすことができます。
したがって、ページ出力キャッシュを使用してもアプリケーションの効率は向上しませんが、ダウンストリーム キャッシュ テクノロジによってドキュメントがキャッシュされるため、サーバーの負荷が軽減される可能性があります。もちろん、これは単なる匿名コンテンツである可能性があります。ダウンストリームに送信されると、それらのリクエストは二度と表示されなくなり、アクセスを防ぐための認証を実行することもできなくなります。
ヒント 8 — IIS 6.0 を実行する (カーネル キャッシュにのみ使用します)
IIS 6.0 (Windows Server? 2003) を実行していない場合は、Microsoft Web サーバーのいくつかの優れたパフォーマンス強化を利用できません。ヒント 7 では、出力キャッシュについて説明しました。 IIS 5.0 では、要求は IIS を経由して ASP.NET に送信されます。キャッシュに関しては、ASP.NET の HttpModule が要求を受信し、キャッシュの内容を返します。
IIS 6.0 を使用している場合は、ASP.NET へのコード変更を必要としないカーネル キャッシュと呼ばれる優れた機能が見つかります。 ASP.NET による出力キャッシュの要求が行われると、IIS カーネル キャッシュはキャッシュされたデータのコピーを受け取ります。ネットワーク ドライバーから要求が送信されると、カーネル レベルのドライバー (コンテキストをユーザー モードに切り替えることなく) が要求を受信し、キャッシュされている場合はキャッシュされたデータを応答にフラッシュして、実行を完了します。これは、カーネル モード キャッシュを IIS および ASP.NET 出力キャッシュと併用すると、驚くべきパフォーマンス結果が得られることを意味します。 Visual Studio 2005 での ASP.NET の開発中、私は ASP.NET のパフォーマンスを担当するプログラム マネージャーでした。開発者は特定の作業を行いますが、私は毎日行われるすべてのレポートを見ることができます。カーネル モード キャッシュの結果は常に最も興味深いものです。最も一般的な特徴は、IIS がわずか約 5% の CPU 使用率で実行されているにもかかわらず、ネットワークに要求/応答が殺到していることです。これは衝撃的です!もちろん、IIS 6.0 を使用する理由は他にもありますが、カーネル モード キャッシュが最も明白な理由です。
ヒント 9 — Gzip 圧縮を使用する
gzip の使用は必ずしもサーバーのパフォーマンスに影響するわけではありませんが (CPU 使用率の増加が見られる場合があるため)、gzip 圧縮を使用すると、サーバーによって送信されるバイト数を減らすことができます。これにより、ページ速度が向上し、帯域幅の使用量が減少したように感じられます。送信されるデータ、その圧縮率、およびクライアントのブラウザーがそれをサポートしているかどうか (IIS は、gzip 圧縮をサポートしているクライアント (Internet Explorer 6.0 や Firefox など) にのみ gzip 圧縮されたコンテンツを送信します) に応じて、サーバーはサービスを提供できます。さらにリクエスト。実際、返されるデータの量を減らすと、ほぼ毎回、1 秒あたりのリクエスト数が増加します。
Gzip 圧縮は IIS 6.0 に組み込まれており、そのパフォーマンスは IIS 5.0 で使用される gzip 圧縮よりもはるかに優れており、これは良いニュースです。残念ながら、IIS 6.0 で gzip 圧縮を有効にしようとすると、IIS の [プロパティ] ダイアログで設定が見つからないことがあります。 IIS チームは、優れた gzip 機能をサーバーに組み込みましたが、それを有効にするための管理 UI を組み込むのを忘れていました。 gzip 圧縮を有効にするには、IIS 6.0 の XML 構成設定を詳しく調べる必要があります (心が弱らないように)。ちなみに、OrcsWeb でホストされている www.asp.net サーバーに関するこの問題の提起に協力してくれた OrcsWeb の Scott Forsyth に感謝します。
この記事では手順については説明しません。IIS6 Compression に関する Brad Wilson の記事を参照してください。 IIS での ASPX 圧縮の有効化には、ASPX の圧縮の有効化に関するナレッジ ベースの記事もあります。ただし、実装の詳細により、動的圧縮とカーネル キャッシュは IIS 6.0 では同時に存在できないことに注意してください。
ヒント 10 — サーバー コントロールのビュー ステート
ビュー ステートは、生成されたページの非表示の出力フィールドに一部の状態データを格納する ASP.NET の興味深い名前です。ページがサーバーにポストバックされると、サーバーはこのビュー ステート データを解析、検証し、ページのコントロール ツリーに適用し直すことができます。ビュー ステートは、クライアントで状態を保持でき、この状態を保存するために Cookie やサーバー メモリを必要としないため、非常に強力な機能です。多くの ASP.NET サーバー コントロールは、ビュー ステートを使用して、データのページ分割時に表示される現在のページの保存など、ページ要素との対話中に作成された設定を保持します。
ただし、ビューステートの使用にはいくつかの欠点もあります。まず、ページが提供または要求されるたびに、ページの全体的な負荷が増加します。サーバーにポストバックされたビューステート データをシリアル化または逆シリアル化するときにも、追加のオーバーヘッドが発生します。最後に、ビュー ステートにより、サーバー上のメモリ割り当てが増加します。
いくつかのサーバー コントロールには、必要でない場合でもビュー ステートを過剰に使用する傾向があります。その中で最も有名なものは DataGrid です。 ViewState プロパティのデフォルトの動作はオンですが、必要がない場合はコントロール レベルまたはページ レベルでオフにすることができます。コントロール内で、EnableViewState プロパティを false に設定するか、次の設定を使用してページ上でグローバルに設定します。
<%@ ページ EnableViewState="false" %>
ページをポストバックしない場合、またはリクエストごとに常にページ上のコントロールを再生成する場合は、ページ レベルでビュー ステートを無効にする必要があります。
高パフォーマンスの ASP.NET アプリケーションを作成する際に役立つヒントをいくつか紹介しました。この記事の前半で述べたように、これは暫定的なガイドであり、ASP.NET のパフォーマンスに関する最終的な決定ではありません。 (ASP.NET アプリケーションのパフォーマンスの向上については、「ASP.NET のパフォーマンスの向上」を参照してください。) 特定のパフォーマンスの問題を解決する最善の方法は、自分自身の経験を通じてのみ見つけることができます。ただし、これらのヒントは、旅の良い指針となるはずです。ソフトウェア開発では、すべてのアプリケーションが独自のものであるため、絶対的なものはほとんどありません。