著者:ロブ・ハワード 翻訳:熱帯魚
この記事では、次の内容について説明します。
· ASP.NET のパフォーマンスに関する一般的な秘密
· ASP.NET のパフォーマンスを向上させるための役立つヒントとテクニック
· ASP.NET でのデータベースの使用に関する推奨事項
· ASP.NET でのキャッシュとバックグラウンド処理
ASP.NET を使用して Web アプリケーションを作成するのは非常に簡単です。非常に簡単なため、多くの開発者はアプリケーションを十分に動作させるために時間をかけて構築していません。この記事では、高パフォーマンスの Web アプリケーションを作成するための 10 のヒントをお勧めします。 ASP.NET アプリケーションは Web アプリケーションのサブセットにすぎないため、説明の対象を ASP.NET アプリケーションに限定しません。この記事は、Web アプリケーションのパフォーマンスを最適化するための決定的なガイドを目的としたものではありません。これは、1 冊の本で簡単に行うことができます。代わりに、この記事を良い出発点として考えてください。
仕事中毒になる前は、よくロッククライミングに行っていました。登山をする前に、旅行ガイドでルートを確認したり、頂上に行ったことがある人のおすすめを読むのが好きです。しかし、ガイドブックがどれほどよくできていても、難しい目標に挑戦する前に、実際の登山経験が必要です。同様に、パフォーマンスの問題を解決したり、高スループットのサイトを実行したりする必要がある場合にのみ、高パフォーマンスの Web アプリケーションの作成方法を学ぶことができます。
私の個人的な経験は、Microsoft の ASP.NET チームで Foundation Program Manager として働き、 www.asp.net を保守および管理し、いくつかのよく知られた ASP.NET アプリケーション (ASP.NET フォーラム) の 1 つである Community Server の設計を支援したことに由来しています。 、.Text、nGallery が 1 つのプラットフォームに接続されています)。私が役に立ったこれらのヒントのいくつかは、あなたにも役立つと確信しています。
アプリケーションを複数の論理層に分割することを検討する必要があります。 3 層 (または n 層) アーキテクチャについて聞いたことがあるかもしれません。これらは通常、ビジネスおよび/またはハードウェアを機能部門に物理的に分割する規定の構造パターンです。システムに大規模なスケールが必要な場合は、ハードウェアを簡単に追加できます。ただし、これによりビジネス ジャンプやマシン ジャンプに伴うパフォーマンスの低下が生じるため、回避する必要があります。したがって、可能な限り、ASP.NET ページとそのページの関連コンポーネントを同じアプリケーションで実行するようにしてください。
コードの分離とレイヤー間の境界により、Web サービスまたはリモート処理を使用すると、パフォーマンスが 20% 以上低下する可能性があります。
データ層は少し異なります。通常、データベース専用のハードウェアを使用する方が良いからです。ただし、データベースにジャンプするプロセスのコストは依然として高いため、コードを最適化するときはデータ層のパフォーマンスを最初に考慮する必要があります。
アプリケーションのパフォーマンス問題の解決に投資する前に、必ずアプリケーションを分析して問題の根本原因を見つけてください。主要なパフォーマンス カウンター (ガベージ コレクションの実行に費やされた時間の割合を示すカウンターなど) も、アプリケーションが時間の大部分を費やしている場所を見つけるのに非常に役立ちます。ただし、時間を費やす場所は直感的ではないことがよくあります。
この記事では、パフォーマンスを向上させる 2 つの方法について説明します。ASP.NET キャッシュの使用などの大規模な最適化と、頻繁に繰り返される小規模な最適化です。これらの小さな最適化が最も興味深い場合もあります。コードに加えた小さな変更は何千回も呼び出されます。大きなチャンクを最適化すると、全体的なパフォーマンスが大幅に向上する可能性があります。小さな単位で最適化すると、特定のリクエストから数マイクロ秒を削減できる可能性がありますが、1 日あたりのすべてのリクエストの累積では、予想外のパフォーマンスの向上が得られます。
データ層のパフォーマンス
アプリケーションのパフォーマンスの最適化を開始する場合、優先順位を付けることができる決定的なテストが 1 つあります。それは、コードがデータベースにアクセスする必要があるかどうかです。もしそうなら、どのくらいの頻度で訪問しますか?このテストは Web サービスやリモート コントロールを使用するコードにも適用できますが、この記事では説明しません。
コード内の特定のコード パスでデータベース リクエストが必要で、文字列操作など、最適化を優先したい他の場所が見つかった場合は、停止して重要なテストを最初に実行します。対処すべき重大なパフォーマンスの問題がない限り、データベースへの接続にかかる時間、返されるデータの量、データベースとの間で行う操作の最適化に時間を費やしたほうがよいでしょう。
一般的な情報を説明したところで、アプリケーションのパフォーマンスを向上させるための 10 のヒントを見てみましょう。パフォーマンスの向上に最も明らかな影響を与えるものから始めます。
ヒント 1 - 複数の結果セットを返す
データベース コードを調べて、データベースに複数回アクセスするリクエスト パスがあるかどうかを確認してください。このような往復ごとに、アプリケーションが 1 秒あたりに処理できるリクエストの数が減少します。 1 つのデータベース要求で複数の結果セットを返すことにより、データベース通信にかかる全体的な時間を短縮できます。データベース サーバーが管理する必要があるリクエストの数を減らすと、システムのスケーラビリティも向上します。
一般に、動的 SQL ステートメントを使用して複数の結果セットを返すことができますが、私はストアド プロシージャを使用することを好みます。ビジネス ロジックをストアド プロシージャに含めるべきかどうかについては議論の余地がありますが、ストアド プロシージャ内のロジックによって返されるデータを制限できる (データ セットのサイズ、ネットワーク接続にかかる時間が削減され、ネットワーク接続の必要性がなくなる) と考えます。ロジック層データのフィルタリング)、それは良いことです。
SqlCommand インスタンスとその ExecuteReader メソッドを使用して厳密に型指定されたビジネス クラスを生成すると、NextResult を呼び出して結果セット ポインターを前方に移動できます。図 1 は、定義されたクラスを使用して複数の ArrayList を生成するセッションの例を示しています。データベースから必要なデータのみを返すと、サーバー上のメモリ要求が大幅に削減されます。
1// 最初の結果セットを読み取ります
2reader = command.ExecuteReader();
3
4// その結果セットからデータを読み取ります
5while (reader.Read()) {
6 つのサプライヤー.Add(PopulateSupplierFromIDataReader(reader));
7}
8
9// 次の結果セットを読み取ります
10reader.NextResult();
11
12// 2 番目の結果セットからデータを読み取ります
13while (reader.Read()) {
14 個の製品.Add(PopulateProductFromIDataReader(reader));
15}
16
17
ヒント 2 - ページ分割されたデータ アクセス
ASP.NET の DataGrid は、データ ページングのサポートという優れた機能を提供します。 DataGrid でページネーションが設定されている場合、一度に特定の数の結果が表示されます。さらに、結果間を移動するためのページング UI が DataGrid の下部に表示されます。ページ分割された UI を使用すると、表示されたデータを前後に移動して、ページごとに特定の数の結果を表示できます。
しかし、小さな問題があります。ページングに DataGrid を使用する場合、すべてのデータをテーブルにバインドする必要があります。たとえば、データ レイヤーはすべてのデータを返す必要があり、その後、DataGrid は現在のページに基づいて表示されるすべてのレコードを設定する必要があります。 DataGrid ページネーションを使用するときに 100,000 レコードが返された場合、リクエストごとに 99,975 レコードが破棄されます (各ページの容量が 25 レコードであると想定)。レコードの数が増えると、各リクエストでより多くのデータを返さなければならないため、アプリケーションのパフォーマンスに大きな影響を与えます。
より適切なページネーション コードを作成する 1 つの方法は、ストアド プロシージャを使用することです。図 2 は、Nothwind データベース内の Orders データ テーブルをページングするサンプル ストアド プロシージャを示しています。基本的に、ここで行う必要があるのは、ページのインデックスとページの容量を渡すことだけです。データベースは適切な結果セットを計算して返します。
1プロシージャの作成northwind_OrdersPages
2(
3 @PageIndex int、
4 @PageSize int
5)
6AS
7始まり
8DECLARE @PageLowerBound int
9DECLARE @PageUpperBound int
10DECLARE @RowsToReturn int
11
12-- 最初に行数を設定します
13SET @RowsToReturn = @PageSize * (@PageIndex + 1)
14SET ROWCOUNT @RowsToReturn
15
16 -- ページ境界を設定する
17SET @PageLowerBound = @PageSize * @PageIndex
18SET @PageUpperBound = @PageLowerBound + @PageSize + 1
19
20-- 選択結果を保存するための一時テーブルを作成します
21CREATE TABLE #PageIndex
22(
23 IndexId int IDENTITY (1, 1) NOT NULL、
24 オーダーID int
25)
26
27 -- 一時テーブルに挿入
28#PageIndex (注文 ID) に挿入
29セレクト
30 注文ID
31から
32 注文
33注文方法
34 注文ID DESC
35
36 -- 合計数を返します
37注文から COUNT(注文 ID) を選択
38
39-- ページングされた結果を返す
40セレクト
41O.*
42から
43 注文 O、
44 #PageIndex ページインデックス
45どこで
46 O.OrderID = PageIndex.OrderID AND
47 PageIndex.IndexID > @PageLowerBound AND
48 PageIndex.IndexID < @PageUpperBound
49注文方法
50 ページインデックス.インデックスID
51
52END
53
54
コミュニティ サービス期間中に、これらのデータ ページングを行うためのページング サーバー コントロールを作成しました。ヒント 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
アプリケーションでコードの最初の行を書き始める前に、まず考慮すべきことは、ASP.NET のキャッシュ機能を最大限に活用できるようにアプリケーション層を設計することです。
コンポーネントが ASP.NET アプリケーション内で実行される場合は、アプリケーション プロジェクトで System.Web.dll を参照するだけです。キャッシュにアクセスする必要がある場合は、HttpRuntime.Cache プロパティを使用します (このオブジェクトは Page.Cache および HttpContext.Cache を通じてアクセスすることもできます)。
キャッシュされたデータの使用にはいくつかのガイドラインがあります。まず、データを複数回使用できる場合は、キャッシュするのが良い選択です。次に、データが一般的なもので、特定のリクエストやユーザーに固有のものではない場合、データをキャッシュすることは優れたオプションです。データがユーザーまたはリクエストに固有であるものの有効期間が長い場合、キャッシュすることはできますが、頻繁には使用されない可能性があります。 3 番目に、見落とされがちな原則は、キャッシュが多すぎる場合があるということです。通常、x86 マシンでは、メモリ不足エラーの可能性を減らすために、800 MB を超えないプライベート バイトを使用するプロセスを実行する必要があります。したがって、キャッシュは制限する必要があります。つまり、1 つの計算の結果を再利用する必要がある場合がありますが、その計算に 10 個のパラメーターが必要な場合は、10 個の置換をキャッシュしようとする必要があり、問題が発生する可能性があります。 ASP.NET では、特に大規模なデータ セットの場合、オーバーキャッシュによるメモリ不足エラーが最も一般的です。
キャッシュには、知っておく必要がある優れた機能がいくつかあります。まず、キャッシュには最も長く使用されていないアルゴリズムが実装されており、これにより、メモリの実行効率が低下した場合に、ASP.NET がキャッシュを強制的にフラッシュ (未使用のアイテムをキャッシュから自動的に削除) できるようになります。次に、キャッシュは、強制的に期限切れにできる期限切れの依存関係をサポートします。これらの依存関係には、時間、キー、ファイルが含まれます。時間はよく使用されますが、ASP.NET 2.0 では、データベース キャッシュの無効化という、より強力な新しい無効化タイプが導入されています。データベース内のデータが変更されたときに、キャッシュ内の項目を自動的に削除することを指します。データベース キャッシュの無効化の詳細については、MSDN マガジン 2004 年 7 月号の「Dino Esposito Cutting Edge」コラムを参照してください。キャッシュのアーキテクチャを理解するには、図 3 を参照してください。
ヒント 5 — リクエストごとのキャッシュ
この記事の前半で、頻繁に通過するコード パスを少し改善するだけで、全体的なパフォーマンスが大幅に向上する可能性があると述べました。これらの小さな改善のうち、間違いなく私のお気に入りの 1 つは、リクエストごとのキャッシュと呼んでいます。
キャッシュ API は、より長期間、または特定の条件が満たされるまでデータをキャッシュするように設計されていますが、リクエストごとのキャッシュとは、そのリクエストの期間中のみデータをキャッシュすることを意味します。リクエストごとに、特定のコード パスが頻繁にアクセスされますが、データの抽出、適用、変更、更新は 1 回だけ行われます。これは少し理論的に聞こえるので、具体的な例を挙げてみましょう。
コミュニティ サーバー フォーラム アプリケーションでは、ページで使用される各サーバー コントロールには、使用する外観、使用するスタイル テーブル、およびその他のパーソナライゼーション データを決定するためのパーソナライゼーション データが必要です。このデータの一部は長期間キャッシュできますが、一部のデータはリクエストごとに 1 回だけフェッチされ、コントロールの外観など、そのリクエスト中に複数回再利用されます。
リクエストごとのキャッシュを実現するには、ASP.NET HttpContext を使用します。リクエストごとに HttpContext インスタンスが作成され、リクエスト中に HttpContext.Current プロパティ内のどこからでもアクセスできます。 HttpContext クラスには特別な Items コレクション プロパティがあり、この Items コレクションに追加されたオブジェクトとデータは、要求の間のみキャッシュされます。キャッシュを使用して頻繁にアクセスされるデータを保存できるのと同じように、HttpContext.Items を使用してリクエストごとにのみ使用されるデータを保存することもできます。その背後にあるロジックは非常に単純です。データが存在しない場合は HttpContext.Items コレクションにデータが追加され、その後の検索では HttpContext.Items 内のデータのみが返されます。
ヒント 6 — バックグラウンド処理
コードへのパスはできるだけ高速である必要があります。リクエストごと、または n リクエストごとに実行される、非常にリソースを大量に消費するタスクを実行していることがわかる場合があります。電子メールの送信や受信データの分析と検証はその一例です。
ASP.NET フォーラム 1.0 を分析し、コミュニティ サーバーを構成するコンテンツを再構築したところ、新しい投稿を公開するためのコード パスが非常に遅いことがわかりました。新しい投稿が公開されるたびに、アプリケーションはまず重複した投稿がないことを確認する必要があります。次に、「悪い言葉」フィルターを使用して投稿を分析し、投稿の文字絵文字を分析し、投稿にタグを付けてインデックスを付け、要求されたら、適切なキューに追加し、添付ファイルを検証し、最後に投稿が公開された直後にすべての購読者に電子メール通知を送信します。明らかに、多くのことが関係しています。
調査の結果、ロジックのインデックス作成と電子メールの送信にほとんどの時間が費やされていることがわかりました。投稿のインデックス作成は非常に時間のかかる操作であり、組み込みの System.Web.Mail 機能が SMTP サーバーに接続し、継続的に電子メールを送信することが判明しました。特定の投稿またはトピック領域の購読者の数が増加するにつれて、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 ページがあり、すべての要求でこのコードを実行すると同じ出力が生成される場合、次の目的で使用できるツールがあります。ページ出力キャッシュの優れた代替手段です。
ページの先頭に次の行を追加します。
<%@ ページ出力キャッシュ VaryByParams="none" 継続時間="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 は、Internet Explorer 6.0 や Firefox など、gzip 圧縮をサポートするクライアントにのみ 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 のパフォーマンスの向上」を参照してください。) 特定のパフォーマンスの問題を解決する最善の方法は、自分自身の経験を通じてのみ見つけることができます。ただし、これらのヒントは、旅の良い指針となるはずです。ソフトウェア開発では、すべてのアプリケーションが独自のものであるため、絶対的なものはほとんどありません。
補足記事「パフォーマンスに関する一般的な誤解」を参照してください。
Rob Howard は、高性能 Web アプリケーション、知識ベース管理、およびコラボレーション システムを専門とする Teligent Systems の創設者です。 Rob は以前 Microsoft に勤務しており、ASP.NET 1.0、1.1、および 2.0 のインフラストラクチャの設計を支援しました。ロブに連絡するには、 [email protected]にアクセスしてください。
元のリンク: http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx