ASP.NET應用程序性能優化(根據資料歸納整理)

 影響ASP.NET程序性能的主要原因分析
• 服務器響應時間過長
– 服務器運算量過大
– 頁面獲取的數據獲取時間過長
• 網絡傳輸問題
– 網絡傳輸質量不好
– 傳輸數據量過大
• 本地系統問題
– 本地硬件配置過低
– 頁面具有性能設置缺陷

頁面和服務器控件處理

 • 下列準則提供了有效使用ASP.NET 頁面和控件的建議

– 避免與服務器間的過多往返行程

– 使用Page.IsPostback 避免往返行程上的額外工作

Page_PreInit-Page_Init- Page_Load— Control events —Page_PreRender —Page_Unload

– 謹慎適當地使用服務器控件

檢查您的應用程序代碼以確保對ASP.NET服務器控件的使用是必要的。即使它們非常易於使用,但是服務器控件並不總是完
成任務的最佳選擇,因爲它們會使用服務器資源。在許多情況下,一個簡單的呈現或數據綁定代入就可以完成任務。

– 避免過多的服務器控件視圖狀態

自動視圖狀態管理是服務器控件的功能,該功能使服務器控件可以在往返過程上重新填充它們的屬性值(您不需要
編寫任何代碼)。但是,因爲服務器控件的視圖狀態在隱藏的窗體字段中往返於服務器,所以該功能確實會對性能產生影響。您應該知道在哪些情況下視圖狀態會有所幫助,在哪些情況下它影響頁的性能。例如,如果您將服務器控件綁定到每個往返過程上的數據,則將用從數據綁定操作獲得的新值替換保存的視圖狀態。在這種情況下,禁用視圖狀態可以節省處理時間。默認情況下,爲所有服務器控件啓用視圖狀態。若要禁用視圖狀態,請將控件的EnableViewState 屬性設置爲false

<asp:datagrid EnableViewState="false" datasource="..." runat="server"/>
<%@ Page EnableViewState="false" %>
 

<asp:datagrid EnableViewState="false" datasource="..." runat="server"/>
<%@ Page EnableViewState="false" %>
Page_PreInit Page_Init Page_Load Control events Page_PreRender Page_Unload

狀態管理

技巧:

當不需要使用的時候在未使用時禁用會話狀態(Session)
– 並不是所有的應用程序或頁都需要具體用戶的會話狀態;您應該在不需要時禁用會話狀態
– 如果頁需要訪問會話變量,但不打算創建或修改它們,則將@Page 指令中的EnableSessionState 屬性設置爲ReadOnly
– 可以禁用XML Web services 方法的會話狀態
– 若要禁用應用程序的會話狀態,請在應用程序的Web.config 文件的SessionState 節中將Mode 屬性設置爲Off
<%@ Page EnableSessionState="false" %>
<sessionState mode="Off" />
[WebMethod(false)]
[WebMethod(EnableSession=false)]

慎重選擇會話狀態提供程序
– 進程內會話狀態
• 迄今爲止速度最快的解決方案
• 如果僅在會話狀態中存儲少量易失數據,則應使用進程內提供程序
– 作爲Windows 服務的進程外會話狀態
– SQL 數據庫中的進程外會話狀態
• 用於跨多個處理器或多個計算機縮放應用程序
• 用於當服務器/進程重新啓動時不能丟失數據的情況


<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424"/>
<sessionState mode="SQLServer" allowCustomSqlDatabase="false"
sqlConnectionString="data source=ben/sql2005;uid=sa"/>
aspnet_regsql.exe -S ben/sql2005 -U sa -ssadd -sstype p
<sessionState mode="InProc"/>

 

數據訪問
• 將SQL 存儲過程用於數據訪問
– 在.NET 框架提供的所有數據訪問方法中,基於SQL 的數據訪問是生成性能最好的可縮放Web 應用程序的最佳選擇
– 使用託管SQL 提供程序時,可通過使用編譯的存儲過程而不是特殊查詢,獲得額外的性能提高
• 使用SqlDataReader 獲得快進只讀數據遊標
– SqlDataReader 對象對從SQL 數據庫中檢索的數據提供前進只讀遊標
– 在ASP.NET 應用程序中使用只讀流,則SqlDataReader 類提供比DataSet 類更高的性能
– SqlDataReader 類使用SQL Server 的本機網絡數據傳輸格式從數據庫連接直接讀取數據
– SqlDataReader 類實現IEnumerable 接口,該接口也使您可以將數據綁定到服務器控件儘可能緩存數據和頁輸出
– 在不需要爲每個頁請求動態計算頁輸出或數據時緩存這些頁輸出或數據
– 通過設計要進行緩存的頁和數據請求(特別是在站點中預期將有較大通訊量的區域),可以優化這些頁的
性能

頁面緩存:

主要有兩種方式
– 使用@ OutputCache指令
– 使用頁面輸出緩存API

使用@OutputCache
• <%@ OutputCache  Duration="#ofseconds" Location="Any |Client | Downstream | Server | None"Shared="True | False"
VaryByControl="controlname"
VaryByCustom="browser | customstring"
VaryByHeader="headers"
VaryByParam="parametername" %>


• Duration
– 頁或用戶控件進行緩存的時間(以秒計)。在頁或用戶控件上設置該屬性爲來自對象的HTTP 響應建立了一個過期策略,並將自動緩存頁或用戶控件輸出。注意該屬性是必需的。如果未包含該屬性,將出現分析器錯誤。
• Location
– OutputCacheLocation 枚舉值之一。默認值爲Any。警告包含在用戶控件(.ascx 文件)中的@ OutputCache 指令不支持此屬性。
• Shared
– 一個布爾值,確定用戶控件輸出是否可以由多個頁共享。默認值爲false。有關詳細信息,請參見備註部分。注意包含在ASP.NET 頁(.aspx 文
件)中的@ OutputCache 指令不支持此屬性。
• VaryByCustom
– 表示自定義輸出緩存要求的任意文本。如果賦予該屬性的值是browser,緩存將隨瀏覽器名稱和主要版本信息的不同而不同。如果輸入
了自定義字符串,您必須在應用程序的Global.asax 文件中重寫HttpApplication.GetVaryByCustomString方法。

VaryByHeader
– 分號分隔的HTTP 標頭列表,用於使輸出緩存發生變化。當將該屬性設爲多標頭時,對於每個指定的標頭,輸出緩存都包含一個請求文檔的不同版本。注意設置VaryByHeader 屬性在所有HTTP 1.1 緩存中啓用緩存項,而不僅限於ASP.NET 緩存。用戶控件中的@ OutputCache 指令不支持此屬性。
• VaryByParam
– 分號分隔的字符串列表,用於使輸出緩存發生變化。默認情況下,這些字符串與用GET 方法屬性發送的查詢字符串值對應,或與用POST 方法發送的參數對應。當將該屬性設置爲多參數時,對於每個指定的參數,輸出緩存都包含一個請求文檔的不同版本。可能的值包括none、* 和任何有效的查詢字符串或POST 參數名稱。警告在輸出緩存ASP.NET 頁時,該屬性是必需的。它對於用戶控件也是必需的,除非已經在用戶控件的@ OutputCache 指令中包含了VaryByControl屬性。如果沒有包含它,則發生分析器錯誤。如果您不想使緩存內容隨任何指定
參數發生變化,請將該值設爲none。如果要使輸出緩存根據所有參數值發生變化,請將屬性設置爲*。
• VaryByControl
– 一個分號分隔的字符串列表,用於更改用戶控件的輸出緩存。這些字符串代表在用戶控件中聲明的ASP.NET 服務器控件的ID 屬性值。注意除非已經包含了VaryByParam 屬性,否則在用戶控件@ OutputCache 指令中,該屬性是必需的。ASP.NET 頁中的@ OutputCache 指令不支持該屬性。如果將Shared 屬性設置爲true,則緩存的用戶控件輸出可以被多個Web 窗體頁訪問。如果不設置爲true,默認行爲是爲包含用戶控件的每一頁緩存用戶控件輸出的一個版本。通過啓用Shared 屬性,可以潛在地節省大量的內存。
– 注意:
• 不要緩存太多項。

緩存每個項均有開銷,特別是在內存使用方面。不要緩存容易重新計算和很少使用的項。其次,給緩存的項分配的有效期不要太短。很快到期的項會導致緩存中不必要的週轉,並且經常導致更多的代碼清除和垃圾回收工作。若關心此問題,請監視與ASP.NETApplications 性能對象關聯的Cache TotalTurnover Rate 性能計數器。高週轉率可能說明存在問題,特別是當項在到期前被移除時。這也稱作內存壓力。
• 給緩存項分配的有效期不要太短

Web 應用程序
• 大型Web 應用程序,請預編譯它
– 減少首次訪問頁時的分析及編譯開銷
• 必要時調整應用程序每個輔助進程的線程數
– 該結構將根據可用於請求的CPU 功率,來決定允許同時執行的請求數。這項技術稱作線程門控
– 使用與“ASP.NET Applications”性能對象關聯的“Pipeline Instance
Count”(管線實例計數)性能計數器,可以在Windows 性能監視器中監視線程門控
– 通過更改Machine.config 配置文件processModel 元素(ASP.NET
設置架構)節中的MaxWorkerThreads 和MaxIOThreads 屬性,手動設置進程中的線程數限制
– 輔助線程是用來處理ASP.NET 請求的,而IO 線程則是用於爲來自文件、數據庫或XML Web services 的數據提供服務的
• 對於廣泛依賴外部資源的應用程序,請考慮在多處理器計算機上啓用網絡園藝

• 禁用調試模式
• 優化Web 服務器和特定應用程序的配置文件
– 僅對需要的應用程序啓用身份驗證
• 默認情況下,ASP.NET 應用程序的身份驗證模式爲Windows 或集成的NTLM
• 大多數情況下,最好僅對需要身份驗證的應用程序在Machine.config 文件中禁用身份驗證,並在Web.config 文件中啓用身份驗證
– 根據適當的請求和響應編碼設置來配置應用程
• ASP.NET 默認編碼格式爲UTF-8
• 如果您的應用程序僅使用ASCII 字符,請配置您的ASCII 應用程序以獲得稍許的性能提高
<compilation debug="true">
<globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
<authentication mode="Forms">
<forms name="SDP" loginUrl="login.aspx" protection="All" path="/" >
</authentication>

優化Web 服務器和特定應用程序的配置文件
– 考慮對應用程序禁用AutoEventWireup
• 重寫Page 對象的OnLoad 方法,而不是使用Page_Load 方法
– 從請求處理管線中移除不用的模塊
<pages autoEventWireup="false"/>

優化技巧和要點

不要依賴代碼中的異常
– 因爲異常大大地降低性能,所以您不應該將它們用作控制正常程序流程的方式。如果有可能檢測到代碼中可能導致異常的狀態,請執行這種操作。不要在處理該狀態之前捕獲異常本身。

– 檢查空值,分配給將分析爲數字值的字符串,在應用數學運算前檢查特定值
// This is not recommended.
try {
result = 100 / num;
}
catch (Exception e) {
result = 0;
}
// This is preferred.
if (num != 0)
result = 100 / num;
else
result = 0;

對字符串連接使用Response.Write
– 在頁面或用戶控件中對字符串連接使用HttpResponse.Write 方法
– 大量字符串連接時不要使用+ ,應使用StringBuilder來構造
Response.Write("a")
Response.Write(myString)
Response.Write("b")
Response.Write(myObj.ToString())
Response.Write("c")
Response.Write(myString2)
Response.Write("d")
string strWrite;
strWrite = "ABC";
strWrite += strTest;
strWrite += …;
StringBuilder sb = new StringBuilder();
sb.Append("ABC");
sb.Append(strTest);

適當地使用公共語言運行庫的垃圾回收器和自動內存管理
– 不要對每個請求使用過多內存(如在內存中存儲大型對象或數據集),因爲這樣垃圾回收器將必須更頻繁地進行更多的工作
– 當不再需要對象時,請不要在代碼中保留不必要的對象引用,因爲在它們仍然被引用的情況下,垃圾回收器將無法釋放資源
– 儘量避免使用含Finalize 方法的對象,因爲它們在後面會導致更多垃圾回收器工作
• 將大量調用的COM 組件移植爲託管代碼
– 大的性能障礙之一是將數據從非託管環境封送到託管環境
– 在交互操作中,請在任何一端執行儘可能多的任務,然後進行單個調用而不是一系列小調用
– 例如,公共語言運行庫中的所有字符串都是Unicode 的,所以應在調用託管代碼之前將組件中的所有字符串轉換成Unicode 格式

避免單線程單元(STA) COM 組件
– 默認情況下,ASP.NET 不允許STA COM 組件在頁內運行
– 若要運行它們,必須在.aspx 文件內將ASPCompat=true 屬性包含
在@ Page 指令中
– 如果必須使用STA COM 組件,則應避免在執行期間進行大量調用,並嘗試在每次調用期間發送儘可能多的信息
– 免在構造頁面期間創建STA COM 組件
<%@ Page Language="VB" ASPCompat="true" %>
<script runat=server>
Dim myComp as new SampleSTAComponent()
Public Sub Page_Load()
myComp.Name = "Sample"
End Sub
</script>
<html>
<%
Response.Write(Server.HtmlEncode(myComp.SayHello))
%>
</html>
<%@ Page Language="VB" ASPCompat="true" %>
<script runat=server>
Dim myComp
Public Sub Page_Load()
myComp = new SampleSTAComponent()
myComp.Name = "Sample"
End Sub
</script>
<html>
<%
Response.Write(Server.HtmlEncode(myComp.SayHello))
%>
</html>

僅對需要的應用程序啓用身
份驗證
• 默認情況下,身份驗證模式爲Windows,或集成NTLM。大多數情況下,對於需要
身份驗證的應用程序,最好在Machine.config 文件中禁用身份驗證,並在Web.config 文件中啓用身份驗證。

選擇適合頁面或應用程序的數據查看機制
• 根據您選擇在Web 窗體頁顯示數據的方式,在便利和性能之間常常存在着重要的權衡。例如,DataGrid Web 服務器控件可能是一種顯示數據的方便快捷的方法,但就性能而言它的開銷常常是最大的。在某些簡單的情況下,您通過生成適當的HTML 自己呈現數據可能很有效,但是自定義和瀏覽器定向會很快抵銷所獲得的額外功效。
Repeater Web 服務器控件是便利和性能的折衷。它高效、可自定義且可編程。

儘量使用客戶端腳本
• 雖然您很可能希望儘量多地使用Web 窗體頁框架的那些節省時間和代碼的功能,但在某些情況下卻不宜使用ASP.NET 服務器控件和回發事件處理。通常,只有在檢索或存儲數據時,您才需要啓動到服務器的往返過程。多數數據操作可在這些往返過程間的客戶端上進行。例如,從HTML窗體驗證用戶輸入經常可在數據提交到服務器之前在客戶端進行。通常,如果不需要將信息傳遞到服務器以將其存儲在數據庫中,那麼您不應該編寫導致往返過程的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章