1. 儘量減少表單回送
每當點擊Web網頁上的Button、LinkButton或ImageButton控件時,表單就會被髮送到服務器上。如果控件的AutoPostBack屬性被設置爲true,如果CheckBox、CheckBoxList等控件的狀態被改變後,也會使表單會發送回服務器。
每次當表單被髮送回服務器,就會被重新加載,啓動Page_Load事件,執行Page_Load事件處理程序中的所有代碼。把網頁的初始化代碼放在這裏是最合適不過的了。我們經常會希望在每次加載網頁時執行一些代碼,而希望只有在網頁第一次加載時執行另一些代碼,甚至希望一些代碼在除首次加載外的每次加載時執行。
可以利用IsPostBack特性來完成這一功能。在網頁第一次加載時,該屬性的值是false。如果網頁因回送而被重新加載,IsPostBack屬性的值就會被設置爲true。通過測試,可以在任意時候執行指定的代碼。下面是相關的C#代碼:
{
// 網頁每次加載時,執行的一些操作
if (!IsPostBack)
{
// 網頁第一次加載時執行的操作
}
else
{
// 回送時執行的操作
}
// 網頁每次加載時執行的操作
}
我們希望儘量不引起回送(每次回送都會要求服務器進行一系列的操作),即使引起回送後。也希望能夠執行儘量少的操作。大規模、浪費時間的操作(例如數據庫查找)尤其應當避免,因爲它們能夠延長應用程序的響應時間。
2. 使用StringBuilder類
字符串在.NET框架中是不可變的,這意味着改變字符串的操作符和方法會返回字符串的改變後的拷貝,這意味着性能還有提高的空間。當進行大量的字符串操作時,使用StringBuilder類就是一種比較好的選擇了。
下面的C#代碼測試用二種方式從10000個子字符串中生成字符串所需要的時間。第一次使用了一個簡單的字符串串聯操作;第二次使用了StringBuilder類。
要想查看結果字符串,可以去掉下面的代碼中註解行的註解符號:
<script runat=”server”>
void Page_Load(Object Source, EventArgs E)
{
int intLimit = 10000;
DateTime startTime;
DateTime endTime;
TimeSpan elapsedTime;
string strSub;
string strWhole = “”;
// 首先執行字符串連接操作
startTime = DateTime.Now;
for (int i=0; i < intLimit; i++)
{
strSub = i.ToString();
strWhole = strWhole + “ “ + strSub;
}
endTime = DateTime.Now;
elapsedTime = endTime - startTime;
lblConcat.Text = elapsedTime.ToString();
// lblConcatString.Text = strWhole;
// 使用stringBuilder類進行同樣的操作
startTime = DateTime.Now;
StringBuilder sb = new StringBuilder();
for (int i=0; i < intLimit; i++)
{
strSub = i.ToString();
sb.Append(“ “);
sb.Append(strSub);
}
endTime = DateTime.Now;
elapsedTime = endTime - startTime;
lblBuild.Text = elapsedTime.ToString();
// lblBuildString.Text = sb.ToString();
}
</script>
<html>
<body>
<form runat=”server”>
<h1>String Concatenation Benchmark</h1>
Concatenation:
<asp:Label id=”lblConcat” runat=”server”/>
<br/>
<asp:Label id=”lblConcatString” runat=”server”/>
<br/> <br/>
StringBuilder:
<asp:Label id=”lblBuild” runat=”server”/>
<br/>
<asp:Label id=”lblBuildString” runat=”server”/>
</form>
</body>
</html>
二種方式的差別是相當大的:使用StringBuilder類的Append方法的速度比使用字符串連接的速度快近200倍。
3. 只在必要時使用服務器端控件
ASP.NET中新引入了一種在服務器端運行的被稱作Web Server Controls的控件,在代碼中,它們經常通過下面的語法被說明:
<asp:TextBox id=”txtLastName” size=”40” runat=”server” /> 它們有時也被稱作ASP控件。服務器端控件是由runat屬性指示的,它的值總是“server”。
通過添加runat屬性,一般的HTML控件可以被很方便地轉換到服務器端運行,下面是一個簡單的例子:
可以通過id屬性中指定的名字,我們可以引用程序中的控件,可以通過編程的方式設置屬性和獲得值,因此,服務器端處理方式有較大的靈活性。
這種靈活性是有一定代價的。每種服務器端控件都會消耗服務器上的資源。
另外,除非控件、網頁或應用程序明確地禁止view state,控件的狀態是包含在view state的隱藏域中,並在每次回送中都會被傳遞,這會引起嚴重的性能下降。
在這方面的一個很好的例子是,網頁上控件表格的應用,如果不需要在代碼中引用表格中的元素,則使用無需進行服務器端處理的HTML表格。我們仍然可以在HTML表格單元中放置服務器控件,並在代碼中引用服務器控件。如果需要引用任意的表格元素,例如指定的單元,則整個表格必須是服務器控件。
4. HyperLink控件、LinkButton控件的差別
對於Web訪問者而言,HyperLink、LinkButton控件是一樣的,但它們在功能方面仍然有較大的差異。當用戶點擊控件時,HyperLink控件會立即將用戶“導航”到目標URL,表件不會回送到服務器上。LinkButton控件則首先將表件發回到服務器,然後將用戶導航到目標URL。如果在“到達”目標URL之前需要進行服務器端處理,則使用LinkButton控件;如果無需進行服務器端處理,則可以使用HyperLink控件。
5. 使用trace方法和trace屬性記錄Page目錄中網頁的執行情況
調試程序的一種古老的技術是在程序中的關健點插入輸出語句,通常情況下,輸出信息中會包含重要變量的值,相關信息可以輸出到屏幕、日誌文件或者數據庫。
在ASP.NET中,通過使用Page命令中的trace屬性,這種調試技術的使用更簡單了。Page命令是ASPX文件開始處的一行代碼,它提供編譯器的指示。Page命令中包含一個或多個屬性,向編譯器提供使用的編程語言、代碼支持文件的位置或要繼承的類的名字等信息。
Page命令中的屬性之一是trace,其值可能是true或false,下面是一個典型的Page命令,其中的trace屬性的值是true:
如果trace屬性的值設置爲true,由ASPX文件生成的Web頁就會顯示出來,除了網頁本身外,關於該頁的大量其他信息也會顯示出來。這些信息以下面小節的形式顯示在一張表格中:
·Request細節 提供Session ID、請求時間和請求的狀態碼。
·Trace Information 包含跟蹤日誌、網頁生命週期中按時間先後順序各個步驟的列表。另外,也可以向其中添加定製信息。
·控件樹 以一種分層次的方式列出網頁上的所有控件,包括每個控件以字節計算的大小。
·Cookies集合 列出該網頁創建的所有Cookie。
·頭部集合 HTTP頭部以及它們的值。
·Server變量 與該網頁相關的Server環境變量。
包含在Trace Information小節中的跟蹤日誌是最有用的,在這裏我們可以插入自己的跟蹤命令。trace類中有2個方法能夠在跟蹤日誌中插入命令:Trace.Write和Trace.Warn,除了Trace.Warn命令用紅色字體顯示、Trace.Write命令用黑色字體顯示外,它們是相同的。下面是跟蹤日誌的一個屏幕快照,其中包含有幾個Trace.Warn命令。
跟蹤日誌中最方便的功能是我們可以在開發和測試過程中在整個代碼中插入Trace.Write和Trace.Warn語句,而在最終交付應用程序時,可以通過改變Page命令中trace屬性的值,禁止這些命令起作用,而無需在部署應用軟件前刪除這些輸出語句。
6.使用.NET命令行
.NET命令行工具在命令提示符窗口中運行。爲了使命令能夠執行,它必須駐留在命令提示符的當前目錄中,或通過設置PATH環境變量。
.NET SDK在“啓動”菜單上安裝一個菜單項,該菜單項能夠打開一個正確設置了PATH環境變量的命令提示符窗口。我們可以通過依次點擊“開始”->“程序”->“Microsoft Visual Studio .NET”->“Visual Studio .NET工具”->“Visual Studio .NET命令提示符”,啓動命令提示符窗口。
通過在將該菜單項從菜單上拖到桌面上時,同時按Ctrl+C鍵,就可以將該菜單項的快捷方式拷貝到桌面上,使用起來會非常方便。