改进性能和样式的 24个 ASP 技巧

 更新时间:2006年09月18日 00:00:00   作者:  

技巧 9:进程外的执行将牺牲可靠性 

ASP 和 MTS/COM+ 都有允许您以可靠性换取性能的配置选项。当建立和部署应用程序时,应当理解这种交换。 

ASP 选项 

ASP 应用程序可以配置为以三种方式之一运行。在 IIS 5.0 中引入了术语"隔离级"来描述这些选项。三个隔离级值分别是低、中和高: 

低级隔离。该隔离级在所有版本的 IIS 中受到支持,并且是最快的。它在主 IIS 进程 Inetinfo.exe 中执行 ASP。如果 ASP 应用程序崩溃,则 IIS 也将崩溃。(要在 IIS 4.0 下重新启动 IIS,Web 站点管理员需要使用工具,如 InetMon,来监视站点,如果服务器失败,将运行批处理文件来重新启动服务器。而 IIS 5.0 则引入了可靠的重新启动,它将自动重新启动失败的服务器。) 
中级隔离。IIS 5.0 引入了这个新隔离级,它称为进程外的,这是因为 ASP 运行在 IIS 进程之外。在中级隔离中,所有被配置按"中级"运行的 ASP 应用程序,将共享单个进程空间。这将减少在一个服务器上运行多个进程外的 ASP 应用程序所需的进程数。中级是 IIS 5.0 中默认的隔离级。 
高级隔离。在 IIS 4.0 和 IIS 5.0 中受到支持,高级隔离也是进程外的。如果 ASP 崩溃,则 Web 服务器并不崩溃。ASP 应用程序将在下一个 ASP 请求时自动重新启动。使用高级隔离,每个被配置为按高级运行的 ASP 应用程序,将在其自己的进程空间中运行。这样可以保护 ASP 应用程序彼此不受干扰。它的缺点是它需要为每个 ASP 应用程序建立独立的进程。当需要在一个服务器上主持十多个应用程序时,会增加很多开销。 
那么,哪个选项是最好的呢?在 IIS 4.0 中,运行进程外的应用程序会极大地影响性能。在 IIS 5.0 中,做了许多工作,使得进程外运行 ASP 应用程序对性能产生的影响降到了最低。实际上,在大多数测试中,在 IIS 5.0 中的 ASP 进程外应用程序,要比 IIS 4.0 中的进程内应用程序运行得更快。无论如何,进程内(低隔离级)在两种平台上仍然产生了最好的性能。但是,如果您的命中率相对较低或最大吞吐量较低,选择低隔离级不会有太大的好处。所以,除非您需要每个 Web 服务器每秒处理数百或数千个页面,否则没有必要选择低隔离级。同样,应当测试多种配置并判断哪种情形最适合您。 

注意: 当您进程外运行 ASP 应用程序(中级或高级隔离)时,则在 NT4 上它们将运行在 MTS 中,而在 Windows 2000 上它们将运行在 COM+ 中。即,在 NT4 上它们运行在 Mtx.exe 中,而在 Windows 2000 上它们运行在 DllHost.exe 中。在"任务管理器"中,您可以看见这些正在运行的进程。还可以看见 IIS 如何为进程外的 ASP 应用程序配置 MTS 程序包或 COM+ 应用程序。 

COM 选项 

COM 组件也有三个配置选项,虽然与 ASP 选项不完全相似。COM 组件可以被:"不配置"、配置为"库应用程序"或配置为"服务器应用程序"。"不配置"是指不向 COM+ 注册组件。组件将运行在调用者的进程空间,就是说,它们是"进程中"的。"库应用程序"也是进程中的,但受惠于 COM+ 的服务,包括安全性、事务和环境支持。"服务器应用程序"被配置为在其自己的进程空间中运行。 

您可能看到,不配置的组件比库应用程序优点稍微多些。您还可能看到"库应用程序"比"服务器应用程序"有很大的性能优点。这是因为"库应用程序"与 ASP 运行在同一个进程中,而"服务器应用程序"则运行在自己的进程中。内部进程调用的开销要比进程内调用的开销大得多。而且,当在进程之间传递数据(如记录集)时,必须在两个进程之间复制所有的数据。 

缺点!当使用"COM 服务器应用程序"时,如果要在 ASP 和 COM 之间传递对象,请确保对象实现"按值汇集",即 MBV。实现 MBV 的对象将其自身从一个进程复制到另一个进程。这比另一种方式好,在另一种方式中,对象留在创建它的进程中,而其他进程则重复调用创建使用该对象的进程。被断开连接的 ADO 记录集将是按值汇集的,已连接的记录集则不是。Scripting.Dictionary 并不实现 MBV,不会在进程之间传递。最后,要另外告诉 VB 程序员的是:MBV 不是通过传递参数 
ByVal 
获得的。MBV 是由原始组件创作者实现的。 

怎么办? 

如果您想要以性能与可靠性的合理交换来完成您的配置,我们的推荐如下: 

在 IIS 4.0 上,使用 ASP 的低隔离级别,并使用"MTS 服务器包"。 
在 IIS 5.0 上,使用 ASP 的中隔离级别,并使用"COM+ 库应用程序"。 
这些是很一般的准则;通常让公司以中或高隔离级别运行 ASP,而单一目的的 Web 服务器可运行于低隔离级别。请权衡折中并自行决定满足需求的配置。 

技巧 10:显式使用选项 

在 .asp 文件中显式使用 
选项 Explicit 
。置于 .asp 文件开头的这一指令,强制开发人员声明所有要使用的变量。许多开发人员认为这有助于调试应用程序,因为它避免了错误键入变量名称而不经意地新建变量(例如, 
MyXLMString=... 
而非 
MyXMLString=) 
。 

也许更重要的是,声明的变量比未声明的变量快。实际上,脚本运行时,在每次使用未声明变量时按照名称引用。而声明的变量,在编译或运行时分配了序号。这样,声明的变量按照该序号引用。由于 
选项 Explicit 
强制变量声明,因此保证声明了所有变量而实现快速访问。 

技巧 11:在子例程和函数中使用局部变量 

局部变量是在子例程和函数中声明的变量。在子例程和函数中,局部变量访问要快于全局变量访问。使用局部变量还可以使代码更加清晰,因此尽可能使用局部变量。 

技巧 12:将常用数据复制到脚本变量 

在 ASP 中访问 COM 时,应该将常用的对象数据复制到脚本变量中。这将削减 COM 方法的调用,COM 方法的调用与访问脚本变量相比,要相对昂贵些。在访问 Collection 和 Dictionary 对象时,这一技术也可以削减了昂贵的查找。 

通常,如果打算多次访问对象数据,请将数据放入脚本变量。该优化的主要目标是 Request 变量(Form 和 QueryString 变量)。例如,您的站点可能传递一个名为 UserID 的 QueryString。假定该 UserID 变量要在特定页中引用 12 次。请不要调用 
Request("UserID") 
12 次,而在 ASP 页的开头将 UserID 赋予某个变量。然后就在页中使用该变量。这将节省 11 次 COM 方法调用。 

在实际中,访问 COM 属性或方法暗藏着繁复的过程和大量的开销。下面是一个示例,它只是些相当普通的代码(从语法上讲): 

Foo.bar.blah.baz = Foo.bar.blah.qaz(1) 
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ... 

在运行这段代码时,将发生下列事件: 

变量 
Foo 
被解析为全局变量。 
变量 
bar 
被解析为 
Foo. 
的成员。这将产生 COM 方法调用。 
变量 
blah 
被解析为 
Foo.bar 
的成员。这也将产生 COM 方法调用。 
变量 
qaz 
被解析为 
foo.bar.blah 
的成员。是的,这也将产生 COM 方法调用。 
调用 
Foo.bar.blah.quaz(1) 
。又一次产生 COM 方法调用。理解这幅图了吗? 
执行步骤 1 到 3 将再次解析 
baz 
。系统不知道调用 
qaz 
是否更改对象模型,因此步骤 1 到 3 必须再次执行解析 
baz 
。 
将 
baz 
解析为 
Foo.bar.blah 
的成员。进行属性置入。 
再次执行步骤 1 到 3 并解析 
zaq 
。 
再次执行步骤 1 到 3 并解析 
abc 
。 
正如所见,这是非常可怕的低效率(而且非常慢)。用 VBScript 编写该代码实现的快速方法为: 

Set myobj = Foo.bar.blah ' 对 blah 做一次解析 
Myobj.baz = myobj.qaz(1) 
If Myobj.zaq = Myobj.abc Then '... 

如果您使用的是 VBScript 5.0 或更高版本,则可用 
With 
语句来写这段代码: 

With Foo.bar.blah 
.baz = .qaz(1) 
If .zaq = .abc Then '... 
... 
End With 

请注意该技巧对 VB 编程同样有效。 

技巧 13:避免重新定义数组 

尽量避免 
Redim 
数组。从关心性能的角度来说,如果计算机受物理内存的限制,最好一开始将数组的维数设置为最差方案 - 而不要将维数设置为最佳方案,再根据需要重新定义维数。这并不意味着明知道不需要那么多而就是应该分配太多的内存。 

下面代码展示了您没有必要地使用了 
Dim 
和 
Redim 
来解决。 

<% 
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" 
%> 

更好的办法是只须一开始 
Dim 
数组为正确的大小(本例中为 5),而不是 
Redim 
数组,再加大数组。这可能会浪费一点儿内存(如果没有用尽所有元素),但是获得的是速度。 

技巧 14:使用响应缓冲 

您可以通过打开"响应缓冲区"来缓冲值得输出的整个页。这将写入浏览器的数据量降为最小,从而提高总体性能。每次写入都会有大量开销(包括 IIS 和通过电缆发送的数据量),因此写入的越少越好。TCP/IP 的工作效率,在发送少量大的数据块时明显高于发送大量小的数据块时,原因在于它的低速启动和 Nagling 算法(用于最小化网络阻塞)。 

打开响应缓冲有两种方法。第一种,可以使用"Internet 服务管理器"为整个应用程序打开响应缓冲。这是推荐的方法,在 IIS 4.0 和 IIS 5.0 中,在默认情况下,为新的 ASP 应用程序打开响应缓冲。第二种,逐页将下列代码行放在 ASP 页的开头,从而启用响应缓冲: 

<% Response.Buffer = True %> 

该行代码必须在任何响应数据写入浏览器之前执行(也就是说,在任何 HTML 出现在 ASP 脚本中之前和任何 Cookies 被使用 
Response.Cookies 
集合设置之前)。通常,最好是为整个应用程序打开响应缓冲。这允许省略上面每页中的代码行。 

Response.Flush 

响应缓冲的通病是用户感觉 ASP 页响应迟钝(尽管总体响应时间改善了),因为他们需要等到整个页生成后才能看见该页。对于长时间运行的页面,可以通过设置 
Response.Buffer = False 
关闭响应缓冲。但是,更好的策略是使用 
Response.Flush 
方法。该方法刷新由 ASP 绘入浏览器的所有 HTML。例如,绘制了具有 1,000 行的表的 100 行后,ASP 可以调用 
Response.Flush 
强制将结果绘制到浏览器;这允许用户在其余的行准备好之前先看到头 100 行。该技术给了您两个举世无双的好东西 - 响应缓冲与浏览器中数据的逐步显示的组合。 

(注意,在上面 1,000 行表的示例中,许多浏览器,在看到 </table> 结束标记之前不会开始绘制表。请检查目标浏览器的支持性。要解决该问题,请将表分割为具有较少行的多个表,然后在每个表后面调用 
Response.Flush 
。新版本的 Internet Explorer 将在表完全下载之前绘制表,特别是如果指定表的列宽则绘制速度更快;这避免强制 Internet Explorer 通过度量每个单元格的内容来计算列宽。) 

响应缓冲的另一个通病是在生成大型页时将使用服务器的大量内存。对于该问题,除了要求生成大型页的技巧外,还可以通过巧妙地使用 
Response.Flush 
来解决。 

技巧 15:批处理内嵌脚本和 Response.Write 语句 

VBScript 语法 
<% = expression %> 
将" 
表达式 
"的值写入 ASP 输出流。如果响应缓冲没有打开,则这些语句的每一句都会导致通过网络,以许多小型包的形式,向浏览器写入数据。这是非常慢的。另外,解释少量脚本和 HTML,将导致在脚本引擎和 HTML 之间切换,也降低了性能。因此,请使用下面技巧:用对 
Response.Write 
的一个调用,替换内嵌的密集组合表达式。例如,在下面范例中,每行每字段有一个对响应流的写入,每行都有许多 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> 

下面是更有效的代码,每行中有一个对响应流的写入。所有代码均包含在一个 VBScript 块内: 

<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> 

当响应缓冲被禁用时,本技巧的作用更大。最好启用响应缓冲,然后观察批处理 
Response.Write 
是否对性能有帮助。 

(在这一特例中,构建表的主体的嵌套循环 ( 
While Not rs.EOF... 
) 可以被精心构造的、对 GetString 的调用所替代。) 

技巧 16:在开始长时间的任务之前先使用 Response.IsClientConnected 

如果用户失去耐心,他们可以在开始执行他们的请求之前放弃 ASP 页。如果他们单击了 Refresh 或跳转到服务器的其他页上,在 ASP 请求队列的末尾将有一个新的请求,而在队列的中间有一个断开连接的请求。这通常发生在服务器处于高负荷的情况下(它有一个很长的请求队列,相应的响应时间也很长),这只能使情况更糟。如果用户不再连接,将没有执行 ASP 页的点(特别是低速、重量级的 ASP 页)。可以使用 
Response.IsClientConnected 
属性检查这种情况。如果它返回 
False 
,则应调用 
Response.End 
并放弃该页的剩余内容。实际上,每当 ASP 要执行新的请求时,IIS 5.0 便将该方法编码,来检查队列中的请求有多长。如果在那里超过了 3 秒钟,ASP 会检查客户是否仍然连接着,如果客户已断开连接,就立即结束该请求。您可以使用 metabase 中的 
AspQueueConnectionTestTime 
设置,调整这 3 秒的超时时间。 

如果有某页执行了很长时间,您可能还想按一定的时间间隔检查 
Response.IsClientConnected 
。在启用响应缓冲之后,按一定的时间间隔执行 
Response.Flush 
,告诉用户正在进行的是哪些事情,是个好办法。 

注意 在 IIS 4.0 中, 
Response.IsClientConnected 
将不能正常工作,除非首先执行 
Response.Write 
。如果启用了缓冲,也需要执行 
Response.Flush 
。在 IIS 5.0 中则不必如此 - 
Response.IsClientConnected 
工作得很好。在任何情况下, 
Response.IsClientConnected 
都要有些开销,所以,只有在执行至少要用 500 毫秒(如果想维持每秒几十页的吞吐量,这是一个很长的时间了)的操作前才使用它。作为通常的规则,不要在紧密循环的每次迭代中调用它,例如当绘制表中的行,可能每 20 行或每 50 行调用一次。 

技巧 17:使用 <OBJECT> 标记实例化对象 

如果需要引用不能在所有代码路径中使用的对象(尤其是服务器 - 或应用程序 - 作用域的对象),则使用 Global.asa 中的 
<object runat=server id=objname> 
标记来声明它们,而不是使用 
Server.createObject 
方法。 
Server.createObject 
立刻创建对象。如果以后不使用那个对象,就不要浪费资源。 
<object id=objname> 
标记声明了 objname,但实际上 objname 此时并没有创建,直到它的方法或属性第一次被使用时才创建。 

这是迟缓计算的另一个例子。 

技巧 18:使用 ADO 对象和其他组件的 TypeLib 声明 

当使用 ADO 时,开发人员经常包含 
adovbs.txt 
来获得对 ADO 不同常量的访问权。该文件必须包含在要使用这些常量的每一页中。该常量文件非常大,给每个 ASP 页增加了很多编译时间和脚本大小方面的开销。 

IIS 5.0 提供了绑定到组件类型库的能力。允许您在每个 ASP 页上引用一次类型库并使用它。每页不需要为编译常量文件付出代价,并且组件开发人员不必为在 ASP 中的使用而生成 VBScript #include 文件。 

要访问 ADO 类型库,请将下列语句之一放入 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:利用浏览器的验证能力 

流行的浏览器具有对以下功能的高级支持,例如 XML、DHTML、Java 小程序以及远程数据服务。请尽量利用这些功能。所有这些技术,都可以通过执行客户端的验证和数据缓存,减少了与 Web 服务器之间的往返。如果您正在运行智能浏览器,该浏览器可以为您进行一些验证(例如,在运行 POST 之前检查信用卡的校验和否有效)。重申一次,请尽量使用这些功能。由于削减了客户端到服务器的往返路程,将减少对 Web 服务器的压力,并且削减了网络通信量(虽然发送给浏览器的初始页面可能更大),服务器访问的所有后端资源也削减了。而且用户不必经常提取新页,使用户的感受好一些。这并不减轻对服务器端验证的需要。还是应该经常进行服务器端的验证。这样能够防止由于某些原因从客户端来的坏数据,例如黑客,或者不运行客户端验证程序的浏览器。 

许多站点由独立于浏览器创建的 HTML 组成。这一点经常阻碍开发人员利用可以提高性能的流行浏览器功能。对于真正高性能的、必须关心浏览器的站点,良好的策略是针对流行的浏览器优化您的页面。在 ASP 中使用"浏览器性能组件",很容易检测到浏览器的功能。诸如 Microsoft FrontPage 等工具,能帮助您设计使用所希望的目标浏览器和 HTML 版本的代码。更详细的讨论,请查看 When is Better Worse? Weighing the Technology Trade-Offs(英文)。 

技巧 20:在循环中避免字符串串联 

许多人在循环中创建类似这样的字符串: 

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 

这种方法有几个问题。首先,重复连接字符串所花费的时间,以二次方曲线的速率增长;粗略地计算,运行循环所花费的时间,与记录数乘以字段数的平方成正比。举一个简单的例子,便能清楚地说明这一点。 

s = "" 
For i = Asc("A") to Asc("Z") 
s = s & Chr(i) 
Next 

在第一次迭代中,得到一个字符的字符串 
"A" 
。在第二次迭代中,VBScript 必须重新分配字符串并复制两个字符 
"AB" 
到 

。在第三次迭代中,它必须再次重新分配 

,并复制三个字符到 

。在第 N 次(26 次)迭代中,它必须重新分配并复制 N 个字符到 

。就是 1+2+3+...+N 的和,为 N*(N+1)/2 次复制。 

在以上记录集的例子中,如果有 100 条记录和 5个字段,则内部的循环将执行 100*5 = 500 次,并且完成所有复制和重新分配所花费时间,将与 500*500 = 250,000 成正比。对一个大小适度的记录集,将有很多次复制。 

在该例子中,代码可以改进:字符串的连接将被 
Response.Write() 
或内嵌脚本 ( 
<% = fld.value %> 
) 所替代。如果打开响应缓冲,这个操作将会很快,因为 
Response.Write 
仅仅将数据添加到响应缓冲的末尾。不再重新分配,因而非常有效。 

特别是在将 ADO 记录集转换到 HTML 表时,请考虑使用 GetRows 或 GetString。 

如果用 JScript 连接字符串,强烈建议使用 
+= 
操作符;即用 
s += "某字符串", 
而不是 
s = s + "某字符串" 
。 

技巧 21:启用浏览器和代理缓存 

默认情况下,ASP 禁用浏览器和代理中的缓存。这将很有意义,因为 ASP 生来就是动态的,具有潜在地对时间敏感的信息。如果有一个不需要对每次查看进行刷新的页,则应该启用浏览器和代理缓存。这使得浏览器和代理能在某一段时间内,使用某一页的缓存副本,这时间的长短可以控制。缓存能明显减轻服务器负荷,使用户的感受好一些。 

哪种动态页可以缓存?举例说明: 

天气页,每 5 分钟更新一次。 
列出新闻的主页或新闻发布的主页,每天更新 2 次。 
公共基金运营列表,基本的统计数小时更新 1 次。 
请注意,使用浏览器或代理缓存,只有很少的命中被记录到 Web 服务器上。如果想精确测量所有页面查看或者张贴广告,也许不喜欢使用浏览器和代理缓存。 

浏览器缓存是由 Web 服务器发往浏览器的 HTTP 截至期限标题控制的。ASP 提供了两种发送标题的机制。要将页面设置为在未来某个分钟数后过期,请设置 
Response.Expires 
属性。以下的例子通知浏览器:内容在 10 分钟后过期: 

<% Response.Expires = 10 %> 

设置 
Response.Expires 
为负数或 0 则禁用缓存。一定要使用较大的负数,例如 -1000 (大于一天),来克服服务器时钟和浏览器时钟之间的差异。第二个属性 
Response.ExpiresAbsolute 
,允许设置内容过期的指定时间: 

<% Response.ExpiresAbsolute = #May 31,2001 13:30:15# %> 

如果不想使用 Response 对象设置过期时间,可以将 <META> 标记写入 HTML,通常写在 HTML 文件的 <HEAD> 内部。一些浏览器会响应这条指令,但代理不会。 

<META HTTP-EQUIV="Expires" value="May 31,2001 13:30:15"> 

最后,可以标识内容对 HTTP 代理缓存是否有效,请使用 
Response.CacheControl 
属性。设置属性为"Public",允许代理缓存内容。 

<% Response.CacheControl = "Public" %> 

默认情况下,该属性设置为"Private"。注意,不应当为显示某用户专用数据的页启用代理缓存,因为代理也许为属于其他用户的用户页面服务。 

技巧 22:尽可能使用 Server.Transfer 替代 Response.Redirect 

Response.Redirect 
通知浏览器,请求一个不同的页面。该函数经常用于重定向用户到登录或错误页面。既然重定向强制一个新页请求,浏览器就必须做两次到 Web 服务器的往返,而且 Web 服务器必须处理额外的请求。IIS 5.0 引入一个新的函数, 
Server.Transfer 
,该函数执行传送到相同服务器上的不同 ASP 页。这样避免了额外的、从浏览器到 Web 服务器的往返,从而改善了整体系统性能,同时改善了对用户的响应时间。请查看重定向中的新方向(英文),它讨论了 
Server.Transfer 
和 
Server.Execute 
。 

也可以查看Leveraging ASP in IIS 5.0中有关 IIS 5.0 和 ASP 3.0 新功能的完全列表。(英文) 

技巧 23:在目录 URL 尾部加斜线 

相关的技巧是,一定要定在指向目录的 URL 尾部加斜线 
(/) 
。如果省略了斜线,浏览器将向服务器提出请求,仅通知它正寻找一个目录。然后浏览器发出第二个请求,在 URL 末尾添加斜线,然后服务器将那个目录的默认文档作为响应,或者如果没有默认文档并且目录浏览已被启用,就以目录列表作为响应。添加了斜线便省去了第一个没用的往返。出于对用户的友好,也许想要在显示的名称的末尾省略斜线。 

例如,写: 

<a href="http://msdn.microsoft.com/workshop/&quo ... uot;MSDN Web 
Workshop">http://msdn.microsoft.com/workshop</a> 

它还适用于指向在 Web 站点主页的 URL:请使用下面的: <a href="http://msdn.microsoft.com/">,不要用 <a href="http://msdn.microsoft.com">. 


技巧 24:避免使用服务器变量 

访问服务器变量将引起 Web 站点向服务器提出特殊的请求,然后收集所有的服务器变量,并不止是需要的那个。这好像从发霉的阁楼中的文件夹中检索某条特殊的信息一样。当想要某条信息时,在访问该信息之前必须先上阁楼取得文件夹。这与请求服务器变量时,性能访问出现第一次请求服务器变量所发生的一样。后续的对其他服务器变量的访问不会引起性能访问。 

从不访问不合格的 Request 对象(例如, 
Request("Data") 
)。对于不在 
Request.Cookies 
、 
Request.Form 
、 
Request.QueryString 
或 
Request.ClientCertificate 
中的项,有对 
Request.ServerVariables 
的隐含调用。 
Request.ServerVariables 
集合比其他集合慢很多。

相关文章

最新评论