快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

提高ASP性能的22个技巧(二)

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

  当访问ASP中的COM对象时,应该将常用对象数据复制到脚本变量中。着将减少COM方式调用。而COM方式调用代价相对比访问脚本数据更高。当访问Collection和
Dictonary对象时,这项技术也能消减高昂的查询代价。

  通常,当预备不止一次访问一个对象数据时,应该将这个数据放当一个脚本对象中。

  这项优化的主要目标是Request变量(Form和QueryString变量)。例如,你的站点传递一个叫UserID的 QueryString变量,假定在一个特定页UserID被引用十次。在ASP页面的顶部,将UserID的值赋给一个变量,来替代十次的调用 Request
("UserID"),将接生9次COM调用。

  在实际中,访问COM属性或方式的昂贵代价可能比较隐蔽。下面是一个例子,显示一段普通的代码:

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

  下面是这段代码运行的步骤:

1. 变量Foo被解析为一个全局对象
2. 变量bar被解析为Foo的一个成员。这触发一次COM方式调用
3. 变量blash被解析为Foo.bar的一个成员。同样,这也触发一次COM方式调用
4. 变量qaz被解析为Foo.bar.blash的一个成员。对,这也触发一次COM方式调用
5. 调用 Foo.bar.blah.qaz(1)。一个或多个COM方式调用。获取图片?
6. 重复步骤1到步骤3来解析baz。系统不知道调用qaz是否会改变对象模型,所以步骤1到步骤3又执行了一次,来解析baz
7. 解析出baz是Foo.bar.blah的一个成员,执行属性put.
8. 重复步骤1到步骤3来解析zaq
9. 重复步骤1到步骤3来解析abc

  正如你所看到的,这是多么低效(并且慢)。迅速的方式是按如下代码写VBScript:

Set myobj = Foo.bar.blah \\\' do the resolution of blah ONCE
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

  技巧13:避免使用可变数组

  尽量避免使用可变数组。既然关心性能,最好还是在数组初始化的时候就设置好它可能的最大大小。当然,这不是说你明知不需要几M的内存,但还是应该给数组分配了那么多。

  下面的代码是一个无理使用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"
%>

  简朴地将数组初始化的时候定义成准确的大小(这里应该是5)远比Redim数组使它变大好。你可能会浪费一些内存(假如你最后没有用完所有的元素),但得到的是速度!

  技巧14:使用响应缓冲(Response Buffering)

  打开“响应缓冲”就可以缓冲整个页面的输出,这样可以减少向浏览器写的次数,提高了总体性能。每次写浏览器都要耗费一定的时间和资源,因此减少写浏览器次数能提高性能;同时,TCP/IP协议发送少的大块数据比发送多的小块数据效率更高。

  有两种方式可以打开响应缓冲。首先,可以使用Internet Service Manager来打开整个应用的响应缓冲。这是推荐的方式。在 IIS 4.0和IIS 5.0中,新建一个应用时,响应缓冲缺省是打开的。第二种方式:针对每个独立的ASP页面,可以通过在页面顶部放置如下代码来打开响应缓冲:

<% Response.Buffer = True %>

  这行语句必须在所有缓冲数据写之前执行(就是说,在所有HTML和通过Response.Cookies设置Cookie之前)。通常,最好是为整个应用打开响应缓冲;这样你就不用在每个ASP页面顶部写上面那条语句了。

Response.Flush

  对于响应缓冲,因为用户在看到东西之前必须等待整个页面生成,所以用户可能够感觉到ASP页面响应比较慢(虽然整体响应时间缩短了);对一个运行时间较长的页面,可以同过Response.Buffer = False 来关掉响应缓冲;但更好的策略是使用Reponse.Flush方式。这个方式把所有已经由ASP生成的HTML输出到浏览器中。例如,一个1,000行的大表,在写完100行之后,ASP可以调用Response.Flush 来强制把结果写到浏览器中,这样,用户就可以在其余行生成之前先看到100行数据。这个技术能让你两全其美―响应缓冲和渐进式地在浏览器表现数据。

  (注重,在上面的1,000行表的例子中,很多浏览器在碰到</table>标记之前可能并不画出整个表。假如想让浏览器逐步显示出数据,可以将一个大表分成多个小表,然后对每个小表调用Response.Flush。新版本的IE会在下载完整个表之前显示表,并且假如指定了表的列宽,显示的速度会更快。)

  另外,当产生一个异常大的页面时,响应缓冲可能会消耗掉许多的服务器内存。这个问题也可以通过使用Response.Flush来解决。

  技巧15:脚本大块化和Response.Write语句

  VBScript语法<% = 表达式 %>把“表达式”的值写到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对性能的提高。

  技巧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 FilesCommon Filessystemadomsado15.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.4ico.com/;; title="4ico.com">http://www.4ico.com<;;/a>

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

  访问服务器端变量将使站点给服务器发送一个特别哀求,收集所有的服务器端变量,不仅仅是你所访问的那一个。
返回类别: 教程
上一教程: 将RECORDSET作为XML保存
下一教程: 判定一个ACCESS数据库中某个表是否存在的方式

您可以阅读与"提高ASP性能的22个技巧(二)"相关的教程:
· 提高ASP性能的22个技巧(一)
· ASP提高首页性能的一个技巧
· 提高ASP性能的最佳选择(续四)
· 提高ASP性能的最佳选择(一)
· 提高ASP性能的最佳选择2
    微笑服务 优质保证 索取样品