改進(jìn)性能和樣式的24個(gè)ASP 技巧
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
簡(jiǎn)介 技巧 1:在 Web 服務(wù)器上緩存常用數(shù)據(jù) 技巧 2:在 Application 或 Session 對(duì)象中緩存常用數(shù)據(jù) 技巧 3:在 Web 服務(wù)器磁盤(pán)上緩存數(shù)據(jù)和 HTML 技巧 4:避免在 Application 或 Session 對(duì)象中緩存非靈活組件 技巧 5:不要在 Application 或 Session 對(duì)象中緩存數(shù)據(jù)庫(kù)連接 技巧 6:妙用 Session 對(duì)象 技巧 7:在 COM 對(duì)象中封裝代碼 技巧 8:晚點(diǎn)獲取資源,早點(diǎn)釋放資源 技巧 9:進(jìn)程外的執(zhí)行將犧牲可靠性 技巧 10:顯式使用選項(xiàng) 技巧 11:在子例程和函數(shù)中使用局部變量 技巧 12:將常用數(shù)據(jù)復(fù)制到腳本變量 技巧 13:避免重新定義數(shù)組 技巧 14:使用響應(yīng)緩沖 技巧 15:批處理內(nèi)嵌腳本和 Response.Write 語(yǔ)句 技巧 16:在開(kāi)始長(zhǎng)時(shí)間的任務(wù)之前先使用 Response.IsClientConnected 技巧 17:使用 <OBJECT> 標(biāo)記實(shí)例化對(duì)象 技巧 18:使用 ADO 對(duì)象和其他組件的 TypeLib 綁定 技巧 19:利用瀏覽器的驗(yàn)證能力 技巧 20:在循環(huán)中避免字符串串聯(lián) 技巧 21:?jiǎn)⒂脼g覽器和代理緩存 技巧 22:盡可能使用 Server.Transfer 替代 Response.Redirect 技巧 23:在目錄 URL 尾部加斜線(xiàn) 技巧 24:避免使用服務(wù)器變量 -------------------------------------------------------------------------------- 簡(jiǎn)介 性能是一個(gè)特性。您需要預(yù)先設(shè)計(jì)性能,或是在日后重新編寫(xiě)應(yīng)用程序。換句話(huà)說(shuō),什么是最大限度優(yōu)化 Active Server Pages (ASP) 應(yīng)用程序性能的好策略? 本文為優(yōu)化 ASP 應(yīng)用程序和"Visual Basic(R) 腳本編輯器 (VBScript)"提供了許多技巧。對(duì)許多陷阱和缺陷進(jìn)行了討論。本文所列的建議均在 http://www.microsoft.com 及其他站點(diǎn)上進(jìn)行了測(cè)試,而且工作正常。本文假定您對(duì) ASP 開(kāi)發(fā)有基本的理解,包括對(duì) VBScript 和/或 JScript、ASP Application、ASP Session 和其他 ASP 內(nèi)部對(duì)象(請(qǐng)求、響應(yīng)和服務(wù)器)。 ASP 的性能,通常不止取決于 ASP 代碼本身。我們并不想在一篇文章中囊括所有的至理名言,只在最后列出與性能相關(guān)的資源。這些鏈接包括 ASP 和非 ASP 主題,包括"ActiveX(R) 數(shù)據(jù)對(duì)象 (ADO)"、"部件對(duì)象模型 (COM)"、數(shù)據(jù)庫(kù)和"Internet 信息服務(wù)器 (IIS)"配置。這些是我們喜歡的鏈接 - 務(wù)請(qǐng)關(guān)注它們。 技巧 1:在 Web 服務(wù)器上緩存常用數(shù)據(jù) 典型的 ASP 頁(yè)從后端數(shù)據(jù)庫(kù)檢索數(shù)據(jù),然后將結(jié)果轉(zhuǎn)換為超文本標(biāo)記語(yǔ)言 (HTML)。無(wú)論數(shù)據(jù)庫(kù)的速度如何,從內(nèi)存檢索數(shù)據(jù)要比從后端數(shù)據(jù)庫(kù)檢索數(shù)據(jù)快得多。從本地硬盤(pán)讀取數(shù)據(jù)通常也要比從數(shù)據(jù)庫(kù)檢索數(shù)據(jù)快得多。因此,通??梢酝ㄟ^(guò)在 Web 服務(wù)器(在內(nèi)存或磁盤(pán))上緩存數(shù)據(jù)來(lái)改善性能。 緩存是典型的空間與時(shí)間的折衷。如果恰當(dāng)?shù)鼐彺鏀?shù)據(jù),您將看到性能會(huì)有驚人的提高。為使緩存發(fā)揮效力,它必須保持經(jīng)常重用的數(shù)據(jù),而且重新計(jì)算這些數(shù)據(jù)的代價(jià)是昂貴的或比較昂貴的。如果緩存充滿(mǎn)了垃圾數(shù)據(jù),則是對(duì)存儲(chǔ)器的浪費(fèi)。 不經(jīng)常變化的數(shù)據(jù)也是緩存的候選數(shù)據(jù),因?yàn)槟鸁o(wú)須擔(dān)心數(shù)據(jù)與數(shù)據(jù)庫(kù)的同步問(wèn)題。組合框、引用表、DHTML 碎片、可擴(kuò)展標(biāo)記語(yǔ)言 (XML) 字符串、菜單項(xiàng)和站點(diǎn)配置變量(包括數(shù)據(jù)源名稱(chēng) (DSN)、Internet 協(xié)議 (IP) 地址和 Web 路徑)都是緩存的候選數(shù)據(jù)。注意,您可以緩存數(shù)據(jù)的表示而不是數(shù)據(jù)本身。如果 ASP 頁(yè)不經(jīng)常更改,而且緩存的成本也非常高(例如,整個(gè)產(chǎn)品目錄),請(qǐng)考慮預(yù)先生成 HTML,而不是在每次請(qǐng)求時(shí)重新繪制。 數(shù)據(jù)應(yīng)緩存在何處,有哪些緩存策略?數(shù)據(jù)經(jīng)常緩存在 Web 服務(wù)器內(nèi)存或 Web 服務(wù)器磁盤(pán)上。下面兩個(gè)技巧討論這些選項(xiàng)。 技巧 2:在 Application 或 Session 對(duì)象中緩存常用數(shù)據(jù) ASP Application 和 Session 對(duì)象為在內(nèi)存中緩存數(shù)據(jù)提供了方便的容器。既可以將數(shù)據(jù)賦予 Application 對(duì)象,也可將數(shù)據(jù)賦予 Session 對(duì)象,這些數(shù)據(jù)在 HTTP 調(diào)用中將保留在內(nèi)存中。Session 數(shù)據(jù)按用戶(hù)存儲(chǔ),而 Application 數(shù)據(jù)在所有用戶(hù)間共享。 何時(shí)將數(shù)據(jù)載入 Application 或 Session?通常,在 Application 或 Session 啟動(dòng)時(shí)加載數(shù)據(jù)。要在 Application 或 Session 啟動(dòng)時(shí)加載數(shù)據(jù),請(qǐng)?jiān)谙旅鎯珊瘮?shù)中添加相應(yīng)的代碼: Application_OnStart() 或 Session_OnStart() 。這兩個(gè)函數(shù)應(yīng)該位于 Global.asa;如果沒(méi)有,可以添加這些函數(shù)。也可以在第一次需要數(shù)據(jù)時(shí)加載數(shù)據(jù)。要進(jìn)行上述操作,請(qǐng)?jiān)?ASP 頁(yè)中添加一些代碼(或編寫(xiě)可重用的腳本函數(shù)),這些代碼檢查數(shù)據(jù)是否存在,并在數(shù)據(jù)不存在時(shí)加載數(shù)據(jù)。這是稱(chēng)為遲緩計(jì)算的經(jīng)典性能技術(shù)的例子 - 在您的確需要它之前,不進(jìn)行計(jì)算。請(qǐng)看例子: <% Function GetEmploymentStatusList Dim d d = Application("EmploymentStatusList") If d = "" Then ‘' FetchEmploymentStatusList 函數(shù)(不顯示) ‘' 從 DB 中取出數(shù)據(jù),返回?cái)?shù)組 d = FetchEmploymentStatusList() Application("EmploymentStatusList") = d End If GetEmploymentStatusList = d End Function %> 可以為每一塊所需的數(shù)據(jù)編寫(xiě)類(lèi)似的函數(shù)。 數(shù)據(jù)應(yīng)該以什么格式存儲(chǔ)?任何變量類(lèi)型均可存儲(chǔ),因?yàn)樗心_本變量是各不相同的。例如,可以存儲(chǔ)字符串、整型或數(shù)組。通常,您將以這些變量類(lèi)型之一存儲(chǔ) ADO 記錄集的內(nèi)容。若要獲取 ADO 記錄集衍生的數(shù)據(jù),可以手工將數(shù)據(jù)復(fù)制到 VBScript 變量中,每次一個(gè)字段。使用一個(gè) ADO 記錄集保留函數(shù) GetRows()、GetString() 或 Save() (ADO 2.5),會(huì)更快更簡(jiǎn)便。完整而詳細(xì)的內(nèi)容已超出了本文的范圍。下面的演示函數(shù)使用了 GetRows() 來(lái)返回記錄集數(shù)據(jù)的數(shù)組: ‘' 取記錄集,以數(shù)組返回 Function FetchEmploymentStatusList Dim rs Set rs = createObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" FetchEmploymentStatusList = rs.GetRows() ‘' 以數(shù)組返回?cái)?shù)據(jù) rs.Close Set rs = Nothing End Function 對(duì)上面示例的進(jìn)一步改進(jìn)應(yīng)當(dāng)是緩存該列表的 HTML,而不是緩存數(shù)組。下面是一個(gè)簡(jiǎn)單的范例: ‘' 取記錄集,以"HTML 選項(xiàng)"列表返回 Function FetchEmploymentStatusList Dim rs, fldName, s Set rs = createObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" s = "<select name=""EmploymentStatus">" & vbCrLf Set fldName = rs.Fields("StatusName") ‘' ADO 字段綁定 Do Until rs.EOF ‘' 下面一行違背了不要進(jìn)行字符串連接, ‘' 但這是可以的,因?yàn)槲覀冋诮⒏咚倬彺? s = s & " <option>" & fldName & "</option>" & vbCrLf rs.MoveNext Loop s = s & "</select>" & vbCrLf rs.Close Set rs = Nothing ‘' 參見(jiàn)盡早釋放 FetchEmploymentStatusList = s ‘' 以字符串返回?cái)?shù)據(jù) End Function 在正常的情況下,可以在 Application 或 Session 作用域中緩存 ADO 記錄集本身。有兩個(gè)警告: ADO 必須為標(biāo)記的自由線(xiàn)程 必須使用斷開(kāi)連接的記錄集。 如果不能保證滿(mǎn)足這兩個(gè)要求,請(qǐng)不要緩存 ADO 記錄集。在下面的非靈活組件和不要緩存連接技巧中,我們將討論在 Application 或 Session 作用域中存儲(chǔ) COM 對(duì)象的危險(xiǎn)。 如果在 Application 或 Session 作用域中存儲(chǔ)數(shù)據(jù),這些數(shù)據(jù)將一直保留在那兒,直到在程序中改變它、Session 過(guò)期或 Web 應(yīng)用程序重新啟動(dòng)時(shí)為止。數(shù)據(jù)需要更新如何處理?若要用手工強(qiáng)制更新應(yīng)用程序數(shù)據(jù),可以調(diào)用只允許管理員訪(fǎng)問(wèn)的數(shù)據(jù)更新 ASP 頁(yè)。另外,還可以通過(guò)函數(shù),周期地自動(dòng)刷新數(shù)據(jù)。下面的示例存儲(chǔ)帶緩存數(shù)據(jù)的時(shí)間戳,在指定時(shí)間間隔后刷新數(shù)據(jù)。 <% ‘' 未顯示錯(cuò)誤處理... Const update_INTERVAL = 300 ‘' 刷新時(shí)間間隔,以秒計(jì) ‘' 函數(shù)返回雇傭狀態(tài)列表 Function GetEmploymentStatusList updateEmploymentStatus GetEmploymentStatusList = Application("EmploymentStatusList") End Function ‘' 定期更新緩存的數(shù)據(jù) Sub updateEmploymentStatusList Dim d, strLastupdate strLastupdate = Application("Lastupdate") If (strLastupdate = "") or _ (update_INTERVAL DateDiff("s", strLastupdate, Now)) Then ‘' 注意:此處可能有兩個(gè)或多個(gè)調(diào)用。這是可以的,只不過(guò) ‘' 產(chǎn)生幾個(gè)不必要的取指令罷了(就此有一個(gè)工作區(qū)) ‘' FetchEmploymentStatusList 函數(shù)(不顯示) ‘' 從 DB 中取數(shù)據(jù),返回一個(gè)數(shù)組 d = FetchEmploymentStatusList() ‘' 更新 Application 對(duì)象。用 Application.Lock() ‘' 來(lái)確保一致的數(shù)據(jù) Application.Lock Application("EmploymentStatusList") = d Application("Lastupdate") = CStr(Now) Application.Unlock End If End Sub 其他示例,請(qǐng)參閱具有 Application 數(shù)據(jù)的最快列表框(英文)。 請(qǐng)注意,在 Session 或 Application 對(duì)象中緩存大型數(shù)組并非上策。在訪(fǎng)問(wèn)數(shù)組元素之前,腳本語(yǔ)言的語(yǔ)法要求建立整個(gè)數(shù)組的臨時(shí)副本。例如,如果在 Application 對(duì)象中緩存了將美國(guó)郵政編碼映射到本地氣象站的字符串?dāng)?shù)組,該字符串?dāng)?shù)組有 100,000 個(gè)元素,ASP 在找出一個(gè)字符串之前,必須將所有 100,000 個(gè)氣象站復(fù)制到臨時(shí)數(shù)組中。在這種情況下,建立帶自定義方法的自定義組件,來(lái)存儲(chǔ)氣象站 - 或使用一個(gè)字典組件,也許更好。 請(qǐng)不要在倒洗澡水時(shí)把孩子一同倒掉,對(duì)這種觀點(diǎn)的一個(gè)新的注解是:數(shù)組提供了對(duì)內(nèi)存中相鄰關(guān)鍵-數(shù)據(jù)對(duì)的快速查找和存儲(chǔ)。索引字典比索引數(shù)組要慢。您應(yīng)該根據(jù)具體情況選擇能夠提供最佳性能的數(shù)據(jù)結(jié)構(gòu)。 技巧 3:在 Web 服務(wù)器磁盤(pán)上緩存數(shù)據(jù)和 HTML 有時(shí),數(shù)據(jù)過(guò)多不能在內(nèi)存中進(jìn)行緩存。"過(guò)多"是一種定性的判斷;它取決于打算消耗的內(nèi)存量,還有緩存項(xiàng)的數(shù)量和這些項(xiàng)的檢索頻率??傊?,如果有過(guò)多的數(shù)據(jù)要在內(nèi)存中緩存,請(qǐng)考慮以文本或 XML 文件的形式,在 Web 服務(wù)器的硬盤(pán)上緩存數(shù)據(jù)??梢詫⒃诖疟P(pán)上緩存數(shù)據(jù)和在內(nèi)存中緩存數(shù)據(jù)組合起來(lái),為站點(diǎn)建立最優(yōu)的緩存策略。 注意,在度量單個(gè) ASP 頁(yè)的性能時(shí),在磁盤(pán)上檢索數(shù)據(jù)不一定比從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)快。但是,緩存減輕了數(shù)據(jù)庫(kù)和網(wǎng)絡(luò)的負(fù)荷。在高負(fù)荷情況下,這將明顯提高總體通信量。在查詢(xún)成本很高時(shí)緩存查詢(xún)的結(jié)果,緩存便非常有效,例如多表聯(lián)合或復(fù)雜的存儲(chǔ)過(guò)程,或緩存大型的結(jié)果集。按照慣例,測(cè)試競(jìng)爭(zhēng)方案。 ASP 和 COM 提供了幾種構(gòu)建磁盤(pán)緩存方案的工具。ADO 記錄集的 Save() 和 Open() 函數(shù),保存和加載磁盤(pán)上的記錄集。您可以使用這些方法重寫(xiě)上面 Application 數(shù)據(jù)緩存技巧中的范例代碼,用 Save() 文件替換向 Application 對(duì)象寫(xiě)入數(shù)據(jù)的代碼。 還有其他一些處理文件的組件: Scripting.FileSystemObject 使您能夠創(chuàng)建、讀取和寫(xiě)入文件。 MSXML 是隨 Internet Explorer 提供的 Microsoft(R) XML 解析器,它支持保存和加載 XML 文檔。 LookupTable 對(duì)象(在 MSN 上使用的范例)是從磁盤(pán)加載簡(jiǎn)單列表的良好選擇。 最后,請(qǐng)考慮在磁盤(pán)上緩存數(shù)據(jù)的表示,而不是數(shù)據(jù)本身。預(yù)制的 HTML 可以作為 .htm 或 .asp 文件存儲(chǔ)在磁盤(pán)上;超級(jí)鏈接可以直接指向這些文件??梢允褂蒙虡I(yè)工具,如 XBuilder 或 Microsoft(R) SQL Server 的 Internet 發(fā)行功能來(lái)自動(dòng)化 HTML 生成過(guò)程。另外,可以將 HTML 片段 #include 到 .asp 文件。還可以使用 FileSystemObject 從磁盤(pán)讀取 HTML 文件或使用 XML 進(jìn)行早期調(diào)整(英文)。 技巧 4:避免在 Application 或 Session 對(duì)象中緩存非靈活組件 雖然在 Application 或 Session 對(duì)象中緩存數(shù)據(jù)是個(gè)好主意,但是緩存 COM 對(duì)象可能有嚴(yán)重缺陷。將常用 COM 對(duì)象嵌入 Application 或 Session 對(duì)象通常具有吸引力。遺憾的是,很多 COM 對(duì)象,包括用 Visual Basic 6.0 或更早版本編寫(xiě)的 COM 對(duì)象,在 Application 或 Session 對(duì)象中存儲(chǔ)時(shí)將導(dǎo)致嚴(yán)重的瓶頸。 特別是任何非靈活組件,在 Session 或 Application 對(duì)象中緩存時(shí)將導(dǎo)致性能瓶頸。靈活組件是標(biāo)記為 ThreadingModel=Both 的組件(它聚集了自由線(xiàn)程匯集器 (FTM))或標(biāo)記為 ThreadingModel=Neutral 的組件(Windows(R) 2000 和 COM+ 中新增的"中性"模型。)下列組件是非靈活的: 自由線(xiàn)程組件(除非它們聚集了 FTM)。 單元線(xiàn)程組件。 單線(xiàn)程組件。 已配置組件(Microsoft Transaction Server (MTS)/COM+ 庫(kù)和服務(wù)器包/應(yīng)用程序)為非靈活組件,除非它們是"中性"線(xiàn)程的。單元線(xiàn)程組件和其他非靈活組件最適于在頁(yè)作用域工作(也就是說(shuō),它們?cè)趩蝹€(gè) ASP 頁(yè)上創(chuàng)建和銷(xiāo)毀)。 在 IIS 4.0 中,標(biāo)記為 ThreadingModel=Both 的組件被視為靈活的。在 IIS 5.0 中,這已經(jīng)不夠了。組件不僅必須標(biāo)記為 Both,而且還必須聚集 FTM。靈活性文章說(shuō)明了如何使得用"活動(dòng)模板庫(kù)"編寫(xiě)的 C++ 組件聚集 FTM。請(qǐng)注意,如果組件緩存接口指針,這些指針本身必須為靈活的、或者必須存儲(chǔ)在"COM 全局接口表 (GIT)"中。如果不能重新編譯 Both 線(xiàn)程組件,使它聚集 FTM,則可以將該組件標(biāo)記為 ThreadingModel=Neutral 。另外,如果不希望 IIS 進(jìn)行靈活性檢查(這樣,希望非靈活組件能夠存儲(chǔ)在 Application 或 Session 作用域中),可以在 metabase 中設(shè)置 AspTrackThreadingModel 為 True 。不主張更改 AspTrackThreadingModel 。 如果試圖在 Application 對(duì)象中存儲(chǔ)用 Server.createObject 創(chuàng)建的非靈活組件,IIS 5.0 將產(chǎn)生錯(cuò)誤??梢酝ㄟ^(guò)在 Global.asa 中使用 <object runat=server scope=application ...> 解決該問(wèn)題,但是不主張這樣做,因?yàn)檫@將導(dǎo)致匯集和串行化,說(shuō)明如下。 如果緩存非靈活組件,會(huì)發(fā)生什么錯(cuò)誤呢?緩存在 Session 對(duì)象中的非靈活組件,將把會(huì)話(huà)"鎖定"到某個(gè) ASP 工作器線(xiàn)程。ASP 維護(hù)著一個(gè)工作器線(xiàn)程池,它向請(qǐng)求提供服務(wù)。通常,新的請(qǐng)求由第一個(gè)可用的工作器線(xiàn)程來(lái)處理。如果 Session 被鎖定到某個(gè)線(xiàn)程,則該請(qǐng)求將不得不等待它所關(guān)聯(lián)的線(xiàn)程變?yōu)榭捎?。打個(gè)比方:您進(jìn)入一個(gè)超市,挑選了一些食品,然后在第 3 號(hào)收款臺(tái)交款。從這以后,每當(dāng)您在這個(gè)超市購(gòu)買(mǎi)食品,都不得不始終在第 3 號(hào)收款臺(tái)交款,即使是在其他收款臺(tái)人少或沒(méi)人時(shí)。 將非靈活組件存儲(chǔ)在 Applicaton 作用域甚至?xí)?duì)性能產(chǎn)生更嚴(yán)重的影響。ASP 將不得不創(chuàng)建專(zhuān)用的線(xiàn)程來(lái)運(yùn)行非靈活的、Applicaton 作用域內(nèi)的組件。這將導(dǎo)致兩種后果:所有調(diào)用不得不被匯集到該線(xiàn)程,而且所有調(diào)用被串行化。匯集意味著:參數(shù)不得不存儲(chǔ)在內(nèi)存的共享區(qū);對(duì)該專(zhuān)用線(xiàn)程執(zhí)行昂貴的上下文切換;組件的方法被執(zhí)行;結(jié)果匯集到共享區(qū)域;以及經(jīng)過(guò)另一個(gè)昂貴的上下文切換,使控制權(quán)返回原來(lái)的線(xiàn)程。串行化意味著所有方法必須一個(gè)挨一個(gè)地運(yùn)行(同一時(shí)刻只能運(yùn)行一個(gè)方法)。兩個(gè)不同的 ASP 工作器線(xiàn)程不可能同時(shí)執(zhí)行共享組件上的方法。這將扼殺并行機(jī)制,尤其是在多處理器計(jì)算機(jī)上。更壞的是,所有非靈活的、Application 作用域內(nèi)的組件都將共享一個(gè)線(xiàn)程("Host STA"),所以串行化的影響更加嚴(yán)重。 是否感到困惑?下面我們提出幾個(gè)通用規(guī)則。如果您正在用 Visual Basic (6.0) 或更早版本編寫(xiě)對(duì)象,請(qǐng)不要將它們緩存在 Application 或 Session 對(duì)象中。如果您不知道對(duì)象的線(xiàn)程模型,就不要緩存它。不要緩存非靈活對(duì)象,而應(yīng)當(dāng)在每頁(yè)上創(chuàng)建并釋放它們。對(duì)象將直接運(yùn)行在 ASP 工作器線(xiàn)程上,這樣,將不會(huì)發(fā)生匯集或串行化。如果 COM 對(duì)象正運(yùn)行在 IIS 框中,而且如果它們沒(méi)有花很長(zhǎng)時(shí)間來(lái)初始化和取消,性能將是足夠的。注意,不要用該方法使用單線(xiàn)程對(duì)象。小心:VB 可以創(chuàng)建單線(xiàn)程的對(duì)象!如果您必須以該方式使用單線(xiàn)程的對(duì)象(如 Microsoft Excel 電子表格),則不要期望有很高的吞吐量。 當(dāng) ADO 被標(biāo)記為自由線(xiàn)程時(shí),則緩存 ADO 記錄集是安全的。要將 ADO 標(biāo)記為自由線(xiàn)程,請(qǐng)使用 Makfre15.bat 文件,該文件通常位于如下目錄中:\\Program Files\Common\System\ADO。 警告: 如果您正在用 Microsoft Access 作為數(shù)據(jù)庫(kù),則不應(yīng)當(dāng)將 ADO 標(biāo)記為自由線(xiàn)程。通常,ADO 記錄集還必須是斷開(kāi)連接的,如果您不能控制站點(diǎn)的 ADO 配置(例如,您是獨(dú)立的軟件廠商 [ISV],將 Web 應(yīng)用程序賣(mài)給客戶(hù),然后由他們來(lái)管理他們自己的配置),那么不緩存記錄集可能會(huì)更好。 詞典組件也是靈活對(duì)象。LookupTable 從數(shù)據(jù)文件加載它的數(shù)據(jù),并且它對(duì)組合框數(shù)據(jù)和配置信息是有用的。來(lái)自 Duwamish Books 的 PageCache 對(duì)象提供了目錄語(yǔ)義,和 Caprock Dictionary 的表現(xiàn)一樣。這些對(duì)象或它們的派生對(duì)象可以構(gòu)成有效緩存策略的基礎(chǔ)。注意,Scripting.Dictionary 對(duì)象不是靈活的,所以不應(yīng)當(dāng)存儲(chǔ)在 Application 或 Session 作用域。 技巧 5:不要在 Application 或 Session 對(duì)象中緩存數(shù)據(jù)庫(kù)連接 緩存 ADO 連接通常是不好的策略。如果一個(gè) Connection 對(duì)象存儲(chǔ)在 Application 中,并在所有頁(yè)上使用,那么所有頁(yè)將競(jìng)爭(zhēng)使用該連接。如果 Connection 對(duì)象存儲(chǔ)在 ASP Session 對(duì)象中,那么將為每個(gè)用戶(hù)創(chuàng)建數(shù)據(jù)庫(kù)連接。這將連接池的好處毀于一旦,并對(duì) Web 服務(wù)器和數(shù)據(jù)庫(kù)產(chǎn)生不必要的壓力。 取代緩存數(shù)據(jù)庫(kù)連接的方法是,在每個(gè)使用 ADO 的 ASP 頁(yè)上創(chuàng)建并取消 ADO 對(duì)象。這是個(gè)有效的方法,因?yàn)?IIS 具有內(nèi)置的數(shù)據(jù)庫(kù)連接池。更準(zhǔn)確的說(shuō),IIS 自動(dòng)啟用 OLEDB 和 ODBC 連接池。這確保了創(chuàng)建并取消每個(gè)頁(yè)上的連接將是有效的。 由于被連接的記錄集中存儲(chǔ)有對(duì)數(shù)據(jù)庫(kù)連接的引用,所以,不應(yīng)當(dāng)在 Application 或 Session 對(duì)象中緩存被連接的記錄集。但是,可以安全地緩存斷開(kāi)連接的記錄集,因?yàn)樗话瑢?duì)其數(shù)據(jù)連接的引用。要斷開(kāi)記錄集的連接,請(qǐng)執(zhí)行如下兩個(gè)步驟: Set rs = Server.createObject("ADODB.RecordSet") rs.CursorLocation = adUseClient ‘' 第 1 步 ‘' 植入帶數(shù)據(jù)的記錄集 rs.Open strQuery, strProv ‘' 現(xiàn)在斷開(kāi)記錄集同數(shù)據(jù)提供者和數(shù)據(jù)源的連接 rs.ActiveConnection = Nothing ‘' 第 2 步 有關(guān)連接池的詳細(xì)信息,請(qǐng)參閱 ADO 和 SQL Server(英文)引用。 技巧 6:妙用 Session 對(duì)象 在肯定了在 Applications 和 Sessions 中緩存的優(yōu)點(diǎn)之后,我們建議您避免使用 Session 對(duì)象。下面將會(huì)談到,當(dāng)用于忙碌站點(diǎn)時(shí),Sessions 有幾個(gè)缺點(diǎn)。所謂忙碌,通常是指站點(diǎn)每秒請(qǐng)求數(shù)百頁(yè)或同時(shí)有數(shù)千個(gè)用戶(hù)。該技巧對(duì)于必須進(jìn)行水平擴(kuò)展的站點(diǎn),即那些利用多個(gè)服務(wù)器來(lái)適應(yīng)負(fù)載或執(zhí)行容錯(cuò)功能的站點(diǎn)來(lái)說(shuō),更加重要。對(duì)于較小的站點(diǎn),如 intranet 站點(diǎn),Sessions 的便利,與開(kāi)銷(xiāo)相比也是值得的。 為了翻新,ASP 自動(dòng)為每個(gè)訪(fǎng)問(wèn) Web 服務(wù)器的用戶(hù)創(chuàng)建一個(gè) Session。每個(gè) Session 有大約 10 KB 內(nèi)存開(kāi)銷(xiāo)(在存儲(chǔ)在 Session 中的任何數(shù)據(jù)中是最高的),并使所有的請(qǐng)求都慢了一點(diǎn)。Session 一直保持活動(dòng)狀態(tài),直到達(dá)到可配置的超時(shí)(通常 20 分鐘)為止。 Session 最大的問(wèn)題不是性能而是可伸縮性。Session 不能跨越 Web 服務(wù)器;一旦在一個(gè)服務(wù)器上創(chuàng)建了 Session,它的數(shù)據(jù)就保持在那里。這意味著,如果您在 Web 領(lǐng)域中使用 Sessions,您將不得不為每個(gè)用戶(hù)的請(qǐng)求設(shè)計(jì)一種策略,以便始終將這些請(qǐng)求引向用戶(hù)的 Session 所在的服務(wù)器。這被稱(chēng)為將用戶(hù)"粘"到 Web 服務(wù)器上。術(shù)語(yǔ)"粘性會(huì)話(huà)"即來(lái)源于此。由于 Session 沒(méi)有保持到磁盤(pán)上,所以,當(dāng) Web 服務(wù)器崩潰時(shí),被"粘住"的用戶(hù)將丟失他們的 Sessions 狀態(tài)。 用于實(shí)施粘性會(huì)話(huà)的策略包括硬件和軟件解決方案。如 Windows 2000 Advanced Server 中的網(wǎng)絡(luò)負(fù)載平衡解決方案和 Cisco 公司的"本地指向器"解決方案可以實(shí)施粘性會(huì)話(huà),但以犧牲一些可伸縮性為代價(jià)。這些解決方案并不完美。我們不主張您現(xiàn)在全盤(pán)推翻您的軟件解決方案(我們過(guò)去常用 ISAPI 篩選器和 URL 矯直對(duì)方案進(jìn)行檢查)。 Application 對(duì)象也不能跨越服務(wù)器;如果您需要在 Web 領(lǐng)域內(nèi)共享并更新 Application 數(shù)據(jù),則需要使用后端數(shù)據(jù)庫(kù)。但只讀的 Application 數(shù)據(jù)在 Web 領(lǐng)域中仍然有用。 如果只是為了增加正常運(yùn)行時(shí)間(用于處理故障轉(zhuǎn)移和服務(wù)器維護(hù)),大多數(shù)執(zhí)行重要任務(wù)的站點(diǎn)將需要部署至少兩臺(tái) Web 服務(wù)器。所以,在設(shè)計(jì)執(zhí)行重要任務(wù)的應(yīng)用程序時(shí),您將需要實(shí)施"粘性會(huì)話(huà)",或者簡(jiǎn)單地避開(kāi) Sessions 以及其他任何在單個(gè) Web 服務(wù)器上存儲(chǔ)用戶(hù)狀態(tài)的狀態(tài)管理技術(shù)。 如果當(dāng)前沒(méi)有使用 Sessions,請(qǐng)確保將它們關(guān)閉??梢酝ㄟ^(guò)"Internet 服務(wù)管理器"(請(qǐng)參閱 ISM 文檔)來(lái)為應(yīng)用程序執(zhí)行該操作。如果決定使用 Sessions,可以采取幾個(gè)方法來(lái)將對(duì)性能的影響降低到最小。 可以將不需要 Sessions 的內(nèi)容(如"幫助"屏幕、訪(fǎng)問(wèn)者區(qū)域等)移動(dòng)到關(guān)閉了 Sessions 的、單獨(dú)的 ASP 應(yīng)用程序中。可以逐頁(yè)提示 ASP:在給定的頁(yè)中您不需要 Session 對(duì)象;使用位于 ASP 頁(yè)頂端的如下指令: <% @EnableSessionState=False %> 使用該指令的一個(gè)很好的原因是,Session 給框架集帶來(lái)了有趣的問(wèn)題。ASP 保證任何時(shí)候只執(zhí)行一個(gè)來(lái)自 Session 的請(qǐng)求。這樣可以確保如果瀏覽器為一個(gè)用戶(hù)請(qǐng)求了多個(gè)頁(yè)時(shí),在每一時(shí)刻只有一個(gè) ASP 請(qǐng)求將進(jìn)入 Session;這就避免了在訪(fǎng)問(wèn) Session 對(duì)象時(shí)出現(xiàn)多線(xiàn)程問(wèn)題。遺憾的是,結(jié)果,框架集中的所有頁(yè)均被以串行化方式繪制,一個(gè)接一個(gè)地,而不是同時(shí)地。這樣,用戶(hù)可能不得不等待很長(zhǎng)時(shí)間才能得到所有框架內(nèi)容。這意味著:如果某些框架頁(yè)不信任 Session,一定要使用 @EnableSessionState=False 指令告訴 ASP。 作為使用 Session 對(duì)象的替代方式,有很多方法可以用來(lái)管理 Session 狀態(tài)。對(duì)于狀態(tài)數(shù)量較小的情況(不到 4 KB),通常建議使用 Cookies、QueryString 變量和隱藏形式的變量。對(duì)于較大數(shù)量的數(shù)據(jù),如購(gòu)物推車(chē),則使用后端數(shù)據(jù)庫(kù)是最合適的選擇。關(guān)于在 Web 服務(wù)器領(lǐng)域中的狀態(tài)管理技術(shù)已經(jīng)有很多資料。詳細(xì)信息,請(qǐng)參閱 會(huì)話(huà)狀態(tài)(英文)。 技巧 7:在 COM 對(duì)象中封裝代碼 如果您有很多 VBScript 或 JScript,那么您可以通過(guò)把代碼移動(dòng)到已編譯的 COM 對(duì)象來(lái)經(jīng)常改進(jìn)它們的性能。已編譯的代碼通常比被解釋代碼運(yùn)行得更快。已編譯的 COM 對(duì)象可以通過(guò)"早期綁定"訪(fǎng)問(wèn)其他 COM 對(duì)象,這種調(diào)用 COM 對(duì)象方法的手段,比腳本所使用的"后期綁定"更有效。 將代碼封裝在 COM 對(duì)象種有如下好處(超越性能): COM 對(duì)象是將表達(dá)邏輯與業(yè)務(wù)邏輯分隔開(kāi)來(lái)的好辦法。 COM 對(duì)象啟用了代碼重用。 很多開(kāi)發(fā)商發(fā)現(xiàn),用 VB、C++ 或 Visual J++ 書(shū)寫(xiě)的代碼,比 ASP 更容易調(diào)試。 COM 對(duì)象有一些缺點(diǎn),包括初始開(kāi)發(fā)時(shí)間以及需要不同的編程技巧。需要警告您的是,封裝"少"量的 ASP 可能會(huì)導(dǎo)致性能降低,而不是提高。通常,在少量 ASP 代碼封裝到 COM 對(duì)象時(shí)出現(xiàn)這樣的情況。這時(shí)候,創(chuàng)建和調(diào)用 COM 對(duì)象的開(kāi)銷(xiāo),超過(guò)了已編譯代碼的好處。至于 ASP 腳本和 COM 對(duì)象代碼怎樣合并才能產(chǎn)生最佳性能還有待測(cè)試。注意,與 Windows NT(R) 4.0/IIS 4.0 相比,Microsoft 已經(jīng)在 Windows 2000/IIS 5.0 中極大地提高了腳本和 ADO 性能。這樣,已編譯代碼對(duì) ASP 代碼的性能優(yōu)勢(shì)已經(jīng)隨著 IIS 5.0 的引入而降低。 有關(guān)在 ASP 中使用 COM 對(duì)象的優(yōu)缺點(diǎn)的更多討論,請(qǐng)參閱 ASP 組件準(zhǔn)則和用 COM 和 Microsoft Visual Basic 6.0 對(duì)分布式應(yīng)用程序進(jìn)行編程(英文)。如果您的確部署了 COM 組件,要對(duì)它們進(jìn)行強(qiáng)度測(cè)試是非常重要的。實(shí)際上,所有 ASP 應(yīng)用程序都應(yīng)當(dāng)作為正式過(guò)程進(jìn)行強(qiáng)度測(cè)試。 技巧 8:晚點(diǎn)獲取資源,早點(diǎn)釋放資源 這是個(gè)小技巧。通常,最好晚點(diǎn)獲取資源而要早點(diǎn)釋放資源。這些資源包括 COM 對(duì)象、文件句柄和其他資源。 ADO 連接和記錄集是這種優(yōu)化的首要目標(biāo)。當(dāng)您使用完記錄集,就是說(shuō)用它的數(shù)據(jù)打印完一個(gè)表格后,請(qǐng)立即將它釋放,而不是等到頁(yè)的末尾。將您的 VBScript 變量設(shè)置為 Nothing 是最好的做法。不要讓記錄集簡(jiǎn)單地脫離作用域。同時(shí),應(yīng)當(dāng)釋放任何有關(guān)的 Command 或 Connection 對(duì)象。(不要忘了對(duì)記錄集或"連接"調(diào)用 Close() ,在將它們?cè)O(shè)置為 = Nothing 之前。)這將縮短數(shù)據(jù)庫(kù)必須為您調(diào)整資源的時(shí)間跨度,并將數(shù)據(jù)庫(kù)連接盡可能快地釋放給連接池。 技巧 9:進(jìn)程外的執(zhí)行將犧牲可靠性 ASP 和 MTS/COM+ 都有允許您以可靠性換取性能的配置選項(xiàng)。當(dāng)建立和部署應(yīng)用程序時(shí),應(yīng)當(dāng)理解這種交換。 ASP 選項(xiàng) ASP 應(yīng)用程序可以配置為以三種方式之一運(yùn)行。在 IIS 5.0 中引入了術(shù)語(yǔ)"隔離級(jí)"來(lái)描述這些選項(xiàng)。三個(gè)隔離級(jí)值分別是低、中和高: 低級(jí)隔離。該隔離級(jí)在所有版本的 IIS 中受到支持,并且是最快的。它在主 IIS 進(jìn)程 Inetinfo.exe 中執(zhí)行 ASP。如果 ASP 應(yīng)用程序崩潰,則 IIS 也將崩潰。(要在 IIS 4.0 下重新啟動(dòng) IIS,Web 站點(diǎn)管理員需要使用工具,如 InetMon,來(lái)監(jiān)視站點(diǎn),如果服務(wù)器失敗,將運(yùn)行批處理文件來(lái)重新啟動(dòng)服務(wù)器。而 IIS 5.0 則引入了可靠的重新啟動(dòng),它將自動(dòng)重新啟動(dòng)失敗的服務(wù)器。) 中級(jí)隔離。IIS 5.0 引入了這個(gè)新隔離級(jí),它稱(chēng)為進(jìn)程外的,這是因?yàn)?ASP 運(yùn)行在 IIS 進(jìn)程之外。在中級(jí)隔離中,所有被配置按"中級(jí)"運(yùn)行的 ASP 應(yīng)用程序,將共享單個(gè)進(jìn)程空間。這將減少在一個(gè)服務(wù)器上運(yùn)行多個(gè)進(jìn)程外的 ASP 應(yīng)用程序所需的進(jìn)程數(shù)。中級(jí)是 IIS 5.0 中默認(rèn)的隔離級(jí)。 高級(jí)隔離。在 IIS 4.0 和 IIS 5.0 中受到支持,高級(jí)隔離也是進(jìn)程外的。如果 ASP 崩潰,則 Web 服務(wù)器并不崩潰。ASP 應(yīng)用程序?qū)⒃谙乱粋€(gè) ASP 請(qǐng)求時(shí)自動(dòng)重新啟動(dòng)。使用高級(jí)隔離,每個(gè)被配置為按高級(jí)運(yùn)行的 ASP 應(yīng)用程序,將在其自己的進(jìn)程空間中運(yùn)行。這樣可以保護(hù) ASP 應(yīng)用程序彼此不受干擾。它的缺點(diǎn)是它需要為每個(gè) ASP 應(yīng)用程序建立獨(dú)立的進(jìn)程。當(dāng)需要在一個(gè)服務(wù)器上主持十多個(gè)應(yīng)用程序時(shí),會(huì)增加很多開(kāi)銷(xiāo)。 那么,哪個(gè)選項(xiàng)是最好的呢?在 IIS 4.0 中,運(yùn)行進(jìn)程外的應(yīng)用程序會(huì)極大地影響性能。在 IIS 5.0 中,做了許多工作,使得進(jìn)程外運(yùn)行 ASP 應(yīng)用程序?qū)π阅墚a(chǎn)生的影響降到了最低。實(shí)際上,在大多數(shù)測(cè)試中,在 IIS 5.0 中的 ASP 進(jìn)程外應(yīng)用程序,要比 IIS 4.0 中的進(jìn)程內(nèi)應(yīng)用程序運(yùn)行得更快。無(wú)論如何,進(jìn)程內(nèi)(低隔離級(jí))在兩種平臺(tái)上仍然產(chǎn)生了最好的性能。但是,如果您的命中率相對(duì)較低或最大吞吐量較低,選擇低隔離級(jí)不會(huì)有太大的好處。所以,除非您需要每個(gè) Web 服務(wù)器每秒處理數(shù)百或數(shù)千個(gè)頁(yè)面,否則沒(méi)有必要選擇低隔離級(jí)。同樣,應(yīng)當(dāng)測(cè)試多種配置并判斷哪種情形最適合您。 注意: 當(dāng)您進(jìn)程外運(yùn)行 ASP 應(yīng)用程序(中級(jí)或高級(jí)隔離)時(shí),則在 NT4 上它們將運(yùn)行在 MTS 中,而在 Windows 2000 上它們將運(yùn)行在 COM+ 中。即,在 NT4 上它們運(yùn)行在 Mtx.exe 中,而在 Windows 2000 上它們運(yùn)行在 DllHost.exe 中。在"任務(wù)管理器"中,您可以看見(jiàn)這些正在運(yùn)行的進(jìn)程。還可以看見(jiàn) IIS 如何為進(jìn)程外的 ASP 應(yīng)用程序配置 MTS 程序包或 COM+ 應(yīng)用程序。 COM 選項(xiàng) COM 組件也有三個(gè)配置選項(xiàng),雖然與 ASP 選項(xiàng)不完全相似。COM 組件可以被:"不配置"、配置為"庫(kù)應(yīng)用程序"或配置為"服務(wù)器應(yīng)用程序"。"不配置"是指不向 COM+ 注冊(cè)組件。組件將運(yùn)行在調(diào)用者的進(jìn)程空間,就是說(shuō),它們是"進(jìn)程中"的。"庫(kù)應(yīng)用程序"也是進(jìn)程中的,但受惠于 COM+ 的服務(wù),包括安全性、事務(wù)和環(huán)境支持。"服務(wù)器應(yīng)用程序"被配置為在其自己的進(jìn)程空間中運(yùn)行。 您可能看到,不配置的組件比庫(kù)應(yīng)用程序優(yōu)點(diǎn)稍微多些。您還可能看到"庫(kù)應(yīng)用程序"比"服務(wù)器應(yīng)用程序"有很大的性能優(yōu)點(diǎn)。這是因?yàn)?庫(kù)應(yīng)用程序"與 ASP 運(yùn)行在同一個(gè)進(jìn)程中,而"服務(wù)器應(yīng)用程序"則運(yùn)行在自己的進(jìn)程中。內(nèi)部進(jìn)程調(diào)用的開(kāi)銷(xiāo)要比進(jìn)程內(nèi)調(diào)用的開(kāi)銷(xiāo)大得多。而且,當(dāng)在進(jìn)程之間傳遞數(shù)據(jù)(如記錄集)時(shí),必須在兩個(gè)進(jìn)程之間復(fù)制所有的數(shù)據(jù)。 缺點(diǎn)!當(dāng)使用"COM 服務(wù)器應(yīng)用程序"時(shí),如果要在 ASP 和 COM 之間傳遞對(duì)象,請(qǐng)確保對(duì)象實(shí)現(xiàn)"按值匯集",即 MBV。實(shí)現(xiàn) MBV 的對(duì)象將其自身從一個(gè)進(jìn)程復(fù)制到另一個(gè)進(jìn)程。這比另一種方式好,在另一種方式中,對(duì)象留在創(chuàng)建它的進(jìn)程中,而其他進(jìn)程則重復(fù)調(diào)用創(chuàng)建使用該對(duì)象的進(jìn)程。被斷開(kāi)連接的 ADO 記錄集將是按值匯集的,已連接的記錄集則不是。Scripting.Dictionary 并不實(shí)現(xiàn) MBV,不會(huì)在進(jìn)程之間傳遞。最后,要另外告訴 VB 程序員的是:MBV 不是通過(guò)傳遞參數(shù) ByVal 獲得的。MBV 是由原始組件創(chuàng)作者實(shí)現(xiàn)的。 怎么辦? 如果您想要以性能與可靠性的合理交換來(lái)完成您的配置,我們的推薦如下: 在 IIS 4.0 上,使用 ASP 的低隔離級(jí)別,并使用"MTS 服務(wù)器包"。 在 IIS 5.0 上,使用 ASP 的中隔離級(jí)別,并使用"COM+ 庫(kù)應(yīng)用程序"。 這些是很一般的準(zhǔn)則;通常讓公司以中或高隔離級(jí)別運(yùn)行 ASP,而單一目的的 Web 服務(wù)器可運(yùn)行于低隔離級(jí)別。請(qǐng)權(quán)衡折中并自行決定滿(mǎn)足需求的配置。 技巧 10:顯式使用選項(xiàng) 在 .asp 文件中顯式使用 選項(xiàng) Explicit 。置于 .asp 文件開(kāi)頭的這一指令,強(qiáng)制開(kāi)發(fā)人員聲明所有要使用的變量。許多開(kāi)發(fā)人員認(rèn)為這有助于調(diào)試應(yīng)用程序,因?yàn)樗苊饬隋e(cuò)誤鍵入變量名稱(chēng)而不經(jīng)意地新建變量(例如, MyXLMString=... 而非 MyXMLString=) 。 也許更重要的是,聲明的變量比未聲明的變量快。實(shí)際上,腳本運(yùn)行時(shí),在每次使用未聲明變量時(shí)按照名稱(chēng)引用。而聲明的變量,在編譯或運(yùn)行時(shí)分配了序號(hào)。這樣,聲明的變量按照該序號(hào)引用。由于 選項(xiàng) Explicit 強(qiáng)制變量聲明,因此保證聲明了所有變量而實(shí)現(xiàn)快速訪(fǎng)問(wèn)。 技巧 11:在子例程和函數(shù)中使用局部變量 局部變量是在子例程和函數(shù)中聲明的變量。在子例程和函數(shù)中,局部變量訪(fǎng)問(wèn)要快于全局變量訪(fǎng)問(wèn)。使用局部變量還可以使代碼更加清晰,因此盡可能使用局部變量。 技巧 12:將常用數(shù)據(jù)復(fù)制到腳本變量 在 ASP 中訪(fǎng)問(wèn) COM 時(shí),應(yīng)該將常用的對(duì)象數(shù)據(jù)復(fù)制到腳本變量中。這將削減 COM 方法的調(diào)用,COM 方法的調(diào)用與訪(fǎng)問(wèn)腳本變量相比,要相對(duì)昂貴些。在訪(fǎng)問(wèn) Collection 和 Dictionary 對(duì)象時(shí),這一技術(shù)也可以削減了昂貴的查找。 通常,如果打算多次訪(fǎng)問(wèn)對(duì)象數(shù)據(jù),請(qǐng)將數(shù)據(jù)放入腳本變量。該優(yōu)化的主要目標(biāo)是 Request 變量(Form 和 QueryString 變量)。例如,您的站點(diǎn)可能傳遞一個(gè)名為 UserID 的 QueryString。假定該 UserID 變量要在特定頁(yè)中引用 12 次。請(qǐng)不要調(diào)用 Request("UserID") 12 次,而在 ASP 頁(yè)的開(kāi)頭將 UserID 賦予某個(gè)變量。然后就在頁(yè)中使用該變量。這將節(jié)省 11 次 COM 方法調(diào)用。 在實(shí)際中,訪(fǎng)問(wèn) COM 屬性或方法暗藏著繁復(fù)的過(guò)程和大量的開(kāi)銷(xiāo)。下面是一個(gè)示例,它只是些相當(dāng)普通的代碼(從語(yǔ)法上講): Foo.bar.blah.baz = Foo.bar.blah.qaz(1) If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ‘' ... 在運(yùn)行這段代碼時(shí),將發(fā)生下列事件: 變量 Foo 被解析為全局變量。 變量 bar 被解析為 Foo. 的成員。這將產(chǎn)生 COM 方法調(diào)用。 變量 blah 被解析為 Foo.bar 的成員。這也將產(chǎn)生 COM 方法調(diào)用。 變量 qaz 被解析為 foo.bar.blah 的成員。是的,這也將產(chǎn)生 COM 方法調(diào)用。 調(diào)用 Foo.bar.blah.quaz(1) 。又一次產(chǎn)生 COM 方法調(diào)用。理解這幅圖了嗎? 執(zhí)行步驟 1 到 3 將再次解析 baz 。系統(tǒng)不知道調(diào)用 qaz 是否更改對(duì)象模型,因此步驟 1 到 3 必須再次執(zhí)行解析 baz 。 將 baz 解析為 Foo.bar.blah 的成員。進(jìn)行屬性置入。 再次執(zhí)行步驟 1 到 3 并解析 zaq 。 再次執(zhí)行步驟 1 到 3 并解析 abc 。 正如所見(jiàn),這是非??膳碌牡托剩ǘ曳浅BS?VBScript 編寫(xiě)該代碼實(shí)現(xiàn)的快速方法為: Set myobj = Foo.bar.blah ‘' 對(duì) blah 做一次解析 Myobj.baz = myobj.qaz(1) If Myobj.zaq = Myobj.abc Then ‘'... 如果您使用的是 VBScript 5.0 或更高版本,則可用 With 語(yǔ)句來(lái)寫(xiě)這段代碼: With Foo.bar.blah .baz = .qaz(1) If .zaq = .abc Then ‘'... ... End With 請(qǐng)注意該技巧對(duì) VB 編程同樣有效。 技巧 13:避免重新定義數(shù)組 盡量避免 Redim 數(shù)組。從關(guān)心性能的角度來(lái)說(shuō),如果計(jì)算機(jī)受物理內(nèi)存的限制,最好一開(kāi)始將數(shù)組的維數(shù)設(shè)置為最差方案 - 而不要將維數(shù)設(shè)置為最佳方案,再根據(jù)需要重新定義維數(shù)。這并不意味著明知道不需要那么多而就是應(yīng)該分配太多的內(nèi)存。 下面代碼展示了您沒(méi)有必要地使用了 Dim 和 Redim 來(lái)解決。 <% Dim MyArray() Redim MyArray(2) MyArray(0) = "hello" MyArray(1) = "good-bye" MyArray(2) = "farewell" ... ‘' 一些別的代碼中,這里您不需要更多的空間,然后 ... Redim Preserve MyArray(5) MyArray(3) = "more stuff" MyArray(4) = "even more stuff" MyArray(5) = "yet more stuff" %> 更好的辦法是只須一開(kāi)始 Dim 數(shù)組為正確的大?。ū纠袨?5),而不是 Redim 數(shù)組,再加大數(shù)組。這可能會(huì)浪費(fèi)一點(diǎn)兒內(nèi)存(如果沒(méi)有用盡所有元素),但是獲得的是速度。 技巧 14:使用響應(yīng)緩沖 您可以通過(guò)打開(kāi)"響應(yīng)緩沖區(qū)"來(lái)緩沖值得輸出的整個(gè)頁(yè)。這將寫(xiě)入瀏覽器的數(shù)據(jù)量降為最小,從而提高總體性能。每次寫(xiě)入都會(huì)有大量開(kāi)銷(xiāo)(包括 IIS 和通過(guò)電纜發(fā)送的數(shù)據(jù)量),因此寫(xiě)入的越少越好。TCP/IP 的工作效率,在發(fā)送少量大的數(shù)據(jù)塊時(shí)明顯高于發(fā)送大量小的數(shù)據(jù)塊時(shí),原因在于它的低速啟動(dòng)和 Nagling 算法(用于最小化網(wǎng)絡(luò)阻塞)。 打開(kāi)響應(yīng)緩沖有兩種方法。第一種,可以使用"Internet 服務(wù)管理器"為整個(gè)應(yīng)用程序打開(kāi)響應(yīng)緩沖。這是推薦的方法,在 IIS 4.0 和 IIS 5.0 中,在默認(rèn)情況下,為新的 ASP 應(yīng)用程序打開(kāi)響應(yīng)緩沖。第二種,逐頁(yè)將下列代碼行放在 ASP 頁(yè)的開(kāi)頭,從而啟用響應(yīng)緩沖: <% Response.Buffer = True %> 該行代碼必須在任何響應(yīng)數(shù)據(jù)寫(xiě)入瀏覽器之前執(zhí)行(也就是說(shuō),在任何 HTML 出現(xiàn)在 ASP 腳本中之前和任何 Cookies 被使用 Response.Cookies 集合設(shè)置之前)。通常,最好是為整個(gè)應(yīng)用程序打開(kāi)響應(yīng)緩沖。這允許省略上面每頁(yè)中的代碼行。 Response.Flush 響應(yīng)緩沖的通病是用戶(hù)感覺(jué) ASP 頁(yè)響應(yīng)遲鈍(盡管總體響應(yīng)時(shí)間改善了),因?yàn)樗麄冃枰鹊秸麄€(gè)頁(yè)生成后才能看見(jiàn)該頁(yè)。對(duì)于長(zhǎng)時(shí)間運(yùn)行的頁(yè)面,可以通過(guò)設(shè)置 Response.Buffer = False 關(guān)閉響應(yīng)緩沖。但是,更好的策略是使用 Response.Flush 方法。該方法刷新由 ASP 繪入瀏覽器的所有 HTML。例如,繪制了具有 1,000 行的表的 100 行后,ASP 可以調(diào)用 Response.Flush 強(qiáng)制將結(jié)果繪制到瀏覽器;這允許用戶(hù)在其余的行準(zhǔn)備好之前先看到頭 100 行。該技術(shù)給了您兩個(gè)舉世無(wú)雙的好東西 - 響應(yīng)緩沖與瀏覽器中數(shù)據(jù)的逐步顯示的組合。 (注意,在上面 1,000 行表的示例中,許多瀏覽器,在看到 </table> 結(jié)束標(biāo)記之前不會(huì)開(kāi)始繪制表。請(qǐng)檢查目標(biāo)瀏覽器的支持性。要解決該問(wèn)題,請(qǐng)將表分割為具有較少行的多個(gè)表,然后在每個(gè)表后面調(diào)用 Response.Flush 。新版本的 Internet Explorer 將在表完全下載之前繪制表,特別是如果指定表的列寬則繪制速度更快;這避免強(qiáng)制 Internet Explorer 通過(guò)度量每個(gè)單元格的內(nèi)容來(lái)計(jì)算列寬。) 響應(yīng)緩沖的另一個(gè)通病是在生成大型頁(yè)時(shí)將使用服務(wù)器的大量?jī)?nèi)存。對(duì)于該問(wèn)題,除了要求生成大型頁(yè)的技巧外,還可以通過(guò)巧妙地使用 Response.Flush 來(lái)解決。 技巧 15:批處理內(nèi)嵌腳本和 Response.Write 語(yǔ)句 VBScript 語(yǔ)法 <% = expression %> 將" 表達(dá)式 "的值寫(xiě)入 ASP 輸出流。如果響應(yīng)緩沖沒(méi)有打開(kāi),則這些語(yǔ)句的每一句都會(huì)導(dǎo)致通過(guò)網(wǎng)絡(luò),以許多小型包的形式,向?yàn)g覽器寫(xiě)入數(shù)據(jù)。這是非常慢的。另外,解釋少量腳本和 HTML,將導(dǎo)致在腳本引擎和 HTML 之間切換,也降低了性能。因此,請(qǐng)使用下面技巧:用對(duì) Response.Write 的一個(gè)調(diào)用,替換內(nèi)嵌的密集組合表達(dá)式。例如,在下面范例中,每行每字段有一個(gè)對(duì)響應(yīng)流的寫(xiě)入,每行都有許多 VBScript 和 HTML 之間的切換: <table> <% For Each fld in rs.Fields %> <th><% = fld.Name %></th> <% Next While Not rs.EOF %> <tr> <% For Each fld in rs.Fields %> <td><% = fld.Value %></td> <% Next </tr> <% rs.MoveNext Wend %> </table> 下面是更有效的代碼,每行中有一個(gè)對(duì)響應(yīng)流的寫(xiě)入。所有代碼均包含在一個(gè) VBScript 塊內(nèi): <table> <% For each fld in rs.Fields Response.Write ("<th>" & fld.Name & "</th>" & vbCrLf) Next While Not rs.EOF Response.Write ("<tr>") For Each fld in rs.Fields %> Response.Write("<td>" & fld.Value & "</td>" & vbCrLf) Next Response.Write "</tr>" Wend %> </table> 當(dāng)響應(yīng)緩沖被禁用時(shí),本技巧的作用更大。最好啟用響應(yīng)緩沖,然后觀察批處理 Response.Write 是否對(duì)性能有幫助。 (在這一特例中,構(gòu)建表的主體的嵌套循環(huán) ( While Not rs.EOF... ) 可以被精心構(gòu)造的、對(duì) GetString 的調(diào)用所替代。) 技巧 16:在開(kāi)始長(zhǎng)時(shí)間的任務(wù)之前先使用 Response.IsClientConnected 如果用戶(hù)失去耐心,他們可以在開(kāi)始執(zhí)行他們的請(qǐng)求之前放棄 ASP 頁(yè)。如果他們單擊了 Refresh 或跳轉(zhuǎn)到服務(wù)器的其他頁(yè)上,在 ASP 請(qǐng)求隊(duì)列的末尾將有一個(gè)新的請(qǐng)求,而在隊(duì)列的中間有一個(gè)斷開(kāi)連接的請(qǐng)求。這通常發(fā)生在服務(wù)器處于高負(fù)荷的情況下(它有一個(gè)很長(zhǎng)的請(qǐng)求隊(duì)列,相應(yīng)的響應(yīng)時(shí)間也很長(zhǎng)),這只能使情況更糟。如果用戶(hù)不再連接,將沒(méi)有執(zhí)行 ASP 頁(yè)的點(diǎn)(特別是低速、重量級(jí)的 ASP 頁(yè))??梢允褂? Response.IsClientConnected 屬性檢查這種情況。如果它返回 False ,則應(yīng)調(diào)用 Response.End 并放棄該頁(yè)的剩余內(nèi)容。實(shí)際上,每當(dāng) ASP 要執(zhí)行新的請(qǐng)求時(shí),IIS 5.0 便將該方法編碼,來(lái)檢查隊(duì)列中的請(qǐng)求有多長(zhǎng)。如果在那里超過(guò)了 3 秒鐘,ASP 會(huì)檢查客戶(hù)是否仍然連接著,如果客戶(hù)已斷開(kāi)連接,就立即結(jié)束該請(qǐng)求。您可以使用 metabase 中的 AspQueueConnectionTestTime 設(shè)置,調(diào)整這 3 秒的超時(shí)時(shí)間。 如果有某頁(yè)執(zhí)行了很長(zhǎng)時(shí)間,您可能還想按一定的時(shí)間間隔檢查 Response.IsClientConnected 。在啟用響應(yīng)緩沖之后,按一定的時(shí)間間隔執(zhí)行 Response.Flush ,告訴用戶(hù)正在進(jìn)行的是哪些事情,是個(gè)好辦法。 注意 在 IIS 4.0 中, Response.IsClientConnected 將不能正常工作,除非首先執(zhí)行 Response.Write 。如果啟用了緩沖,也需要執(zhí)行 Response.Flush 。在 IIS 5.0 中則不必如此 - Response.IsClientConnected 工作得很好。在任何情況下, Response.IsClientConnected 都要有些開(kāi)銷(xiāo),所以,只有在執(zhí)行至少要用 500 毫秒(如果想維持每秒幾十頁(yè)的吞吐量,這是一個(gè)很長(zhǎng)的時(shí)間了)的操作前才使用它。作為通常的規(guī)則,不要在緊密循環(huán)的每次迭代中調(diào)用它,例如當(dāng)繪制表中的行,可能每 20 行或每 50 行調(diào)用一次。 技巧 17:使用 <OBJECT> 標(biāo)記實(shí)例化對(duì)象 如果需要引用不能在所有代碼路徑中使用的對(duì)象(尤其是服務(wù)器 - 或應(yīng)用程序 - 作用域的對(duì)象),則使用 Global.asa 中的 <object runat=server id=objname> 標(biāo)記來(lái)聲明它們,而不是使用 Server.createObject 方法。 Server.createObject 立刻創(chuàng)建對(duì)象。如果以后不使用那個(gè)對(duì)象,就不要浪費(fèi)資源。 <object id=objname> 標(biāo)記聲明了 objname,但實(shí)際上 objname 此時(shí)并沒(méi)有創(chuàng)建,直到它的方法或?qū)傩缘谝淮伪皇褂脮r(shí)才創(chuàng)建。 這是遲緩計(jì)算的另一個(gè)例子。 技巧 18:使用 ADO 對(duì)象和其他組件的 TypeLib 聲明 當(dāng)使用 ADO 時(shí),開(kāi)發(fā)人員經(jīng)常包含 adovbs.txt 來(lái)獲得對(duì) ADO 不同常量的訪(fǎng)問(wèn)權(quán)。該文件必須包含在要使用這些常量的每一頁(yè)中。該常量文件非常大,給每個(gè) ASP 頁(yè)增加了很多編譯時(shí)間和腳本大小方面的開(kāi)銷(xiāo)。 IIS 5.0 提供了綁定到組件類(lèi)型庫(kù)的能力。允許您在每個(gè) ASP 頁(yè)上引用一次類(lèi)型庫(kù)并使用它。每頁(yè)不需要為編譯常量文件付出代價(jià),并且組件開(kāi)發(fā)人員不必為在 ASP 中的使用而生成 VBScript #include 文件。 要訪(fǎng)問(wèn) ADO 類(lèi)型庫(kù),請(qǐng)將下列語(yǔ)句之一放入 Global.asa 中。 <!-- METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library" TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" --> 或者 <!-- METADATA TYPE="TypeLib" FILE="C:\Program Files\Common Files\system\ado\msado15.dll" --> 技巧 19:利用瀏覽器的驗(yàn)證能力 流行的瀏覽器具有對(duì)以下功能的高級(jí)支持,例如 XML、DHTML、Java 小程序以及遠(yuǎn)程數(shù)據(jù)服務(wù)。請(qǐng)盡量利用這些功能。所有這些技術(shù),都可以通過(guò)執(zhí)行客戶(hù)端的驗(yàn)證和數(shù)據(jù)緩存,減少了與 Web 服務(wù)器之間的往返。如果您正在運(yùn)行智能瀏覽器,該瀏覽器可以為您進(jìn)行一些驗(yàn)證(例如,在運(yùn)行 POST 之前檢查信用卡的校驗(yàn)和否有效)。重申一次,請(qǐng)盡量使用這些功能。由于削減了客戶(hù)端到服務(wù)器的往返路程,將減少對(duì) Web 服務(wù)器的壓力,并且削減了網(wǎng)絡(luò)通信量(雖然發(fā)送給瀏覽器的初始頁(yè)面可能更大),服務(wù)器訪(fǎng)問(wèn)的所有后端資源也削減了。而且用戶(hù)不必經(jīng)常提取新頁(yè),使用戶(hù)的感受好一些。這并不減輕對(duì)服務(wù)器端驗(yàn)證的需要。還是應(yīng)該經(jīng)常進(jìn)行服務(wù)器端的驗(yàn)證。這樣能夠防止由于某些原因從客戶(hù)端來(lái)的壞數(shù)據(jù),例如黑客,或者不運(yùn)行客戶(hù)端驗(yàn)證程序的瀏覽器。 許多站點(diǎn)由獨(dú)立于瀏覽器創(chuàng)建的 HTML 組成。這一點(diǎn)經(jīng)常阻礙開(kāi)發(fā)人員利用可以提高性能的流行瀏覽器功能。對(duì)于真正高性能的、必須關(guān)心瀏覽器的站點(diǎn),良好的策略是針對(duì)流行的瀏覽器優(yōu)化您的頁(yè)面。在 ASP 中使用"瀏覽器性能組件",很容易檢測(cè)到瀏覽器的功能。諸如 Microsoft FrontPage 等工具,能幫助您設(shè)計(jì)使用所希望的目標(biāo)瀏覽器和 HTML 版本的代碼。更詳細(xì)的討論,請(qǐng)查看 When is Better Worse? Weighing the Technology Trade-Offs(英文)。 技巧 20:在循環(huán)中避免字符串串聯(lián) 許多人在循環(huán)中創(chuàng)建類(lèi)似這樣的字符串: s = "<table>" & vbCrLf For Each fld in rs.Fields s = s & " <th>" & fld.Name & "</th> " Next While Not rs.EOF s = s & vbCrLf & " <tr>" For Each fld in rs.Fields s = s & " <td>" & fld.Value & "</td> " Next s = s & " </tr>" rs.MoveNext Wend s = s & vbCrLf & "</table>" & vbCrLf Response.Write s 這種方法有幾個(gè)問(wèn)題。首先,重復(fù)連接字符串所花費(fèi)的時(shí)間,以二次方曲線(xiàn)的速率增長(zhǎng);粗略地計(jì)算,運(yùn)行循環(huán)所花費(fèi)的時(shí)間,與記錄數(shù)乘以字段數(shù)的平方成正比。舉一個(gè)簡(jiǎn)單的例子,便能清楚地說(shuō)明這一點(diǎn)。 s = "" For i = Asc("A") to Asc("Z") s = s & Chr(i) Next 在第一次迭代中,得到一個(gè)字符的字符串 "A" 。在第二次迭代中,VBScript 必須重新分配字符串并復(fù)制兩個(gè)字符 "AB" 到 。在第三次迭代中,它必須再次重新分配 ,并復(fù)制三個(gè)字符到 。在第 N 次(26 次)迭代中,它必須重新分配并復(fù)制 N 個(gè)字符到 。就是 1+2+3+...+N 的和,為 N*(N+1)/2 次復(fù)制。 在以上記錄集的例子中,如果有 100 條記錄和 5個(gè)字段,則內(nèi)部的循環(huán)將執(zhí)行 100*5 = 500 次,并且完成所有復(fù)制和重新分配所花費(fèi)時(shí)間,將與 500*500 = 250,000 成正比。對(duì)一個(gè)大小適度的記錄集,將有很多次復(fù)制。 在該例子中,代碼可以改進(jìn):字符串的連接將被 Response.Write() 或內(nèi)嵌腳本 ( <% = fld.Value %> ) 所替代。如果打開(kāi)響應(yīng)緩沖,這個(gè)操作將會(huì)很快,因?yàn)? Response.Write 僅僅將數(shù)據(jù)添加到響應(yīng)緩沖的末尾。不再重新分配,因而非常有效。 特別是在將 ADO 記錄集轉(zhuǎn)換到 HTML 表時(shí),請(qǐng)考慮使用 GetRows 或 GetString。 如果用 JScript 連接字符串,強(qiáng)烈建議使用 += 操作符;即用 s += "某字符串", 而不是 s = s + "某字符串" 。 技巧 21:?jiǎn)⒂脼g覽器和代理緩存 默認(rèn)情況下,ASP 禁用瀏覽器和代理中的緩存。這將很有意義,因?yàn)?ASP 生來(lái)就是動(dòng)態(tài)的,具有潛在地對(duì)時(shí)間敏感的信息。如果有一個(gè)不需要對(duì)每次查看進(jìn)行刷新的頁(yè),則應(yīng)該啟用瀏覽器和代理緩存。這使得瀏覽器和代理能在某一段時(shí)間內(nèi),使用某一頁(yè)的緩存副本,這時(shí)間的長(zhǎng)短可以控制。緩存能明顯減輕服務(wù)器負(fù)荷,使用戶(hù)的感受好一些。 哪種動(dòng)態(tài)頁(yè)可以緩存?舉例說(shuō)明: 天氣頁(yè),每 5 分鐘更新一次。 列出新聞的主頁(yè)或新聞發(fā)布的主頁(yè),每天更新 2 次。 公共基金運(yùn)營(yíng)列表,基本的統(tǒng)計(jì)數(shù)小時(shí)更新 1 次。 請(qǐng)注意,使用瀏覽器或代理緩存,只有很少的命中被記錄到 Web 服務(wù)器上。如果想精確測(cè)量所有頁(yè)面查看或者張貼廣告,也許不喜歡使用瀏覽器和代理緩存。 瀏覽器緩存是由 Web 服務(wù)器發(fā)往瀏覽器的 HTTP 截至期限標(biāo)題控制的。ASP 提供了兩種發(fā)送標(biāo)題的機(jī)制。要將頁(yè)面設(shè)置為在未來(lái)某個(gè)分鐘數(shù)后過(guò)期,請(qǐng)?jiān)O(shè)置 Response.Expires 屬性。以下的例子通知瀏覽器:內(nèi)容在 10 分鐘后過(guò)期: <% Response.Expires = 10 %> 設(shè)置 Response.Expires 為負(fù)數(shù)或 0 則禁用緩存。一定要使用較大的負(fù)數(shù),例如 -1000 (大于一天),來(lái)克服服務(wù)器時(shí)鐘和瀏覽器時(shí)鐘之間的差異。第二個(gè)屬性 Response.ExpiresAbsolute ,允許設(shè)置內(nèi)容過(guò)期的指定時(shí)間: <% Response.ExpiresAbsolute = #May 31,2001 13:30:15# %> 如果不想使用 Response 對(duì)象設(shè)置過(guò)期時(shí)間,可以將 <META> 標(biāo)記寫(xiě)入 HTML,通常寫(xiě)在 HTML 文件的 <HEAD> 內(nèi)部。一些瀏覽器會(huì)響應(yīng)這條指令,但代理不會(huì)。 <META HTTP-EQUIV="Expires" VALUE="May 31,2001 13:30:15"> 最后,可以標(biāo)識(shí)內(nèi)容對(duì) HTTP 代理緩存是否有效,請(qǐng)使用 Response.CacheControl 屬性。設(shè)置屬性為"Public",允許代理緩存內(nèi)容。 <% Response.CacheControl = "Public" %> 默認(rèn)情況下,該屬性設(shè)置為"Private"。注意,不應(yīng)當(dāng)為顯示某用戶(hù)專(zhuān)用數(shù)據(jù)的頁(yè)啟用代理緩存,因?yàn)榇硪苍S為屬于其他用戶(hù)的用戶(hù)頁(yè)面服務(wù)。 技巧 22:盡可能使用 Server.Transfer 替代 Response.Redirect Response.Redirect 通知瀏覽器,請(qǐng)求一個(gè)不同的頁(yè)面。該函數(shù)經(jīng)常用于重定向用戶(hù)到登錄或錯(cuò)誤頁(yè)面。既然重定向強(qiáng)制一個(gè)新頁(yè)請(qǐng)求,瀏覽器就必須做兩次到 Web 服務(wù)器的往返,而且 Web 服務(wù)器必須處理額外的請(qǐng)求。IIS 5.0 引入一個(gè)新的函數(shù), Server.Transfer ,該函數(shù)執(zhí)行傳送到相同服務(wù)器上的不同 ASP 頁(yè)。這樣避免了額外的、從瀏覽器到 Web 服務(wù)器的往返,從而改善了整體系統(tǒng)性能,同時(shí)改善了對(duì)用戶(hù)的響應(yīng)時(shí)間。請(qǐng)查看重定向中的新方向(英文),它討論了 Server.Transfer 和 Server.Execute 。 也可以查看Leveraging ASP in IIS 5.0中有關(guān) IIS 5.0 和 ASP 3.0 新功能的完全列表。(英文) 技巧 23:在目錄 URL 尾部加斜線(xiàn) 相關(guān)的技巧是,一定要定在指向目錄的 URL 尾部加斜線(xiàn) (/) 。如果省略了斜線(xiàn),瀏覽器將向服務(wù)器提出請(qǐng)求,僅通知它正尋找一個(gè)目錄。然后瀏覽器發(fā)出第二個(gè)請(qǐng)求,在 URL 末尾添加斜線(xiàn),然后服務(wù)器將那個(gè)目錄的默認(rèn)文檔作為響應(yīng),或者如果沒(méi)有默認(rèn)文檔并且目錄瀏覽已被啟用,就以目錄列表作為響應(yīng)。添加了斜線(xiàn)便省去了第一個(gè)沒(méi)用的往返。出于對(duì)用戶(hù)的友好,也許想要在顯示的名稱(chēng)的末尾省略斜線(xiàn)。 例如,寫(xiě): <a title="MSDN Web Workshop">http://msdn.microsoft.com/workshop</a> 它還適用于指向在 Web 站點(diǎn)主頁(yè)的 URL:請(qǐng)使用下面的: <a >,不要用 <a >. 技巧 24:避免使用服務(wù)器變量 訪(fǎng)問(wèn)服務(wù)器變量將引起 Web 站點(diǎn)向服務(wù)器提出特殊的請(qǐng)求,然后收集所有的服務(wù)器變量,并不止是需要的那個(gè)。這好像從發(fā)霉的閣樓中的文件夾中檢索某條特殊的信息一樣。當(dāng)想要某條信息時(shí),在訪(fǎng)問(wèn)該信息之前必須先上閣樓取得文件夾。這與請(qǐng)求服務(wù)器變量時(shí),性能訪(fǎng)問(wèn)出現(xiàn)第一次請(qǐng)求服務(wù)器變量所發(fā)生的一樣。后續(xù)的對(duì)其他服務(wù)器變量的訪(fǎng)問(wèn)不會(huì)引起性能訪(fǎng)問(wèn)。 從不訪(fǎng)問(wèn)不合格的 Request 對(duì)象(例如, Request("Data") )。對(duì)于不在 Request.Cookies 、 Request.Form 、 Request.QueryString 或 Request.ClientCertificate 中的項(xiàng),有對(duì) Request.ServerVariables 的隱含調(diào)用。
Request.ServerVariables 集合比其他集合慢很多。 該文章在 2011/2/16 10:33:27 編輯過(guò) |
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)... |