精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● ASP>>ASP技巧>>22个提高ASP性能的技巧(3)

主题:22个提高ASP性能的技巧(3)
发信人: i_am_trueman(粗蚊)
整理人: i_am_trueman(2004-02-28 19:30:40), 站内信件
技巧16:在进入长时运算之前使用Resonse.IsClientConnected  
如果用户感到不耐烦,他们可能在ASP页面计算他们的请求之前离开这个页面。如果他们点击刷新或是跳到服务器上的另一个页面,新的请求将位于ASP请求队列尾部,而中断的请求却在请求队列的中部;通常服务器在高负载情况下可能发生这种情况(服务器有很长的请求队列,同时请求次数也很多);而这种情况又使服务器的负载情况变得更加恶劣。如果用户已经断掉连接,没有必要再执行这个ASP页面(尤其当这是一个很慢、很耗资源的页面时);Response.IsClientConnected属性能检查出这种情  
况;如果属性返回False,就应该调用Resonse.End来结束剩余的页面。事实上,  
IIS 5.0使这种检查规律划--无论什么时候ASP准备执行一个新的请求,他先检查请求队列有多长;如果队列已经超过3秒钟,ASP就会检查客户端是否连接;如果客户端已经断开,ASP立即终止这个请求。可以使用AspQueueConnectionTestTime设置来调整3秒的超时。  

如果有一个非常耗时的页面要执行,也可以在页面中检查  
Response.IsClientConnected。当响应缓冲打开时,在页面运行中使用  
Response.Flush也能给用户操作正在执行的感觉。  

注意:在IIS 4.0上,除非你先执行了Response.Write,否则  
Response.IsClientConnected的结果有可能不正确;如果响应缓冲已经打开,还必须先执行Response.Flush。在IIS 5.0上,就没有这个必要了,  
Response.IsClientConnected工作得很正常。无论任何情况,  
Response.IsClientConnected总要消耗一些时间,因此,只应该在执行耗时至少超过500ms的页面中执行。首要原则是,不要在一个紧密的循环中反复调用这个属性。  

技巧17:用<OBJECT>标记来实例化对象  
如果你想在Global.asa中引用一个不在所有的代码路径中使用的对象(特定的服务器 - 或应用 - 范围对象),使用<object runat=server id=objname>标记定义比用Server.CreateObject方法定义更为合适一点。因为Server.CreateObject立即创建对象,但如果过你以后不使用这个对象,则浪费了资源。<object id=objname>只是声明objname,但objname并没有真正创建;objname在第一次使用时才创建。  

技巧18:为ADO和其他组件使用类型库声明  
当使用ADO时,开发者往往通过包含adovbs.txt来访问ADO常量。这个文件必须包含在每个使用常量的页面里;而常量文件还想相当的大,大大增加了处理每页耗费的时间和资源。  


IIS 5.0引入了绑定组件类型库的能力;允许只引用类型库一次,然后就可以在每个ASP页面中使用。每个页面不用在为编译常量文件而消耗资源;组件开发者也不用为ASP准备VBScript包含文件了。  

可以在Global.asa中放入如下语句,来访问ADO类型库:  

<!-- 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:在循环中避免进行字符串连接  
很多人喜欢用如下的循环生成字符串:  

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  

这种方法有一些问题。第一个就是在循环中连接字符串会使时间成二次方  
(quadratic)成长;或者说,运行这个循环的时间同记录的字段数目平方成正比。  
下面简单的例子能更清楚地看见本质:  

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

在第一次循环中,s等于"A";在第二次循环中,VBScript必须重新分配s的空间,并把字符串"AB"赋给s;在第三次循环中,又重新分配s的空间,重新赋值。在第N(26)次循环中,VBScript重新分配并复制了N次字符串给s,所以,总共是  
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 += "some string",不要使用 s = s + "some string"。  

技巧20:使用Server.Transfer代替Response.Redirect  
Response.Redirect告诉浏览器请求另外一页。这个函数经常用来把用户跳转到登录页面或错误页面。既然redirect强制产生新的页面请求,结果就是浏览器和Web服务器间做了两次交互,Web服务器不得不多处理一次额外的请求。IIS 5.0引入了一个新的函数:Server.Transfer;这个函数直接把运行权交给同一个服务器上的另一个页面;避免了额外的浏览器到Web服务器的交互,提高了性能。  

技巧21:在目录URL的尾部加上斜杠(/)  
如果省略了尾部的斜杠,浏览器回发送一个请求给服务器,被告知它的请求是一个目录;然后浏览器再发送一个二次请求,不过这次URL尾部加上了斜杠,然后服务器再次响应浏览器。如果一开始就给URL加上斜杠,便可以省去无用的请求;当然,为了用户友好性,你可以在显示名字时省略尾部斜杠。  

例如,按如下的写法:  

<a href="http://www.asplot.net/faq/" title="ASPLot
FAQ">http://www.asplot.net/faq  

技巧22:避免使用服务器端变量  
访问服务器端变量将使站点给服务器发送一个特殊请求,收集所有的服务器端变量,不仅仅是你所访问的那一个。

[关闭][返回]