改进性能和样式的 24个ASP技巧(三)-ASP技术-3P代码网
繁体中文
设为首页
加入收藏
当前位置:ASP技术首页 >> ASP应用 >> 改进性能和样式的 24个ASP技巧(三)

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

2006-02-15 08:00:00  作者:  来源:互联网  浏览次数:0  文字大小:【】【】【
简介:  技巧 13:避免重新定义数组 尽量避免 Redim 数组。从关心性能的角度来说,如果计算机受物理内存的限制,最好一开始将数组的维数设置为最差方案 - 而不要将维数设置为最佳方案,再根据需要重新定义维数。这并...
关键字:样式 性能 技巧 ASP

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

尽量避免

Redim

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

下面代码展示了您没有必要地使用了

Dim

Redim

来解决。

更好的办法是只须一开始

Dim

数组为正确的大小(本例中为 5),而不是

Redim

数组,再加大数组。这可能会浪费一点儿内存(如果没有用尽所有元素),但是获得的是速度。

技巧 14:使用响应缓冲

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

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

该行代码必须在任何响应数据写入浏览器之前执行(也就是说,在任何 HTML 出现在 ASP 脚本中之前和任何 Cookies 被使用

Response.Cookies

集合设置之前)。通常,最好是为整个应用程序打开响应缓冲。这允许省略上面每页中的代码行。

Response.Flush

响应缓冲的通病是用户感觉 ASP 页响应迟钝(尽管总体响应时间改善了),因为他们需要等到整个页生成后才能看见该页。对于长时间运行的页面,可以通过设置

Response.Buffer = False

关闭响应缓冲。但是,更好的策略是使用

Response.Flush

方法。该方法刷新由 ASP 绘入浏览器的所有 HTML。例如,绘制了具有 1,000 行的表的 100 行后,ASP 可以调用

Response.Flush

强制将结果绘制到浏览器;这允许用户在其余的行准备好之前先看到头 100 行。该技术给了您两个举世无双的好东西 - 响应缓冲与浏览器中数据的逐步显示的组合。

(注意,在上面 1,000 行表的示例中,许多浏览器,在看到

结束标记之前不会开始绘制表。请检查目标浏览器的支持性。要解决该问题,请将表分割为具有较少行的多个表,然后在每个表后面调用

Response.Flush

。新版本的 Internet Explorer 将在表完全下载之前绘制表,特别是如果指定表的列宽则绘制速度更快;这避免强制 Internet Explorer 通过度量每个单元格的内容来计算列宽。)

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

Response.Flush

来解决。

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

VBScript 语法

将"

表达式

"的值写入 ASP 输出流。如果响应缓冲没有打开,则这些语句的每一句都会导致通过网络,以许多小型包的形式,向浏览器写入数据。这是非常慢的。另外,解释少量脚本和 HTML,将导致在脚本引擎和 HTML 之间切换,也降低了性能。因此,请使用下面技巧:用对

Response.Write

的一个调用,替换内嵌的密集组合表达式。例如,在下面范例中,每行每字段有一个对响应流的写入,每行都有许多 VBScript 和 HTML 之间的切换:

<% Next

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

<%

For each fld in rs.Fields

Response.Write ("" & fld.Name & "" & vbCrLf)

Next

While Not rs.EOF

Response.Write ("")

For Each fld in rs.Fields %>

Response.Write("" & fld.Value & "" & vbCrLf)

Next

Response.Write ""

Wend

%>

当响应缓冲被禁用时,本技巧的作用更大。最好启用响应缓冲,然后观察批处理

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:使用 标记实例化对象

如果需要引用不能在所有代码路径中使用的对象(尤其是服务器 - 或应用程序 - 作用域的对象),则使用 Global.asa 中的

标记来声明它们,而不是使用

Server.createObject

方法。

Server.createObject

立刻创建对象。如果以后不使用那个对象,就不要浪费资源。

标记声明了 objname,但实际上 objname 此时并没有创建,直到它的方法或属性第一次被使用时才创建。

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

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

当使用 ADO 时,开发人员经常包含

adovbs.txt

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

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

要访问 ADO 类型库,请将下列语句之一放入 Global.asa 中。

TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" -->

或者

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

" & vbCrLf

For Each fld in rs.Fields

s = s & " " & fld.Name & " "

Next

While Not rs.EOF

s = s & vbCrLf & " "

For Each fld in rs.Fields

s = s & " " & fld.Value & " "

Next

s = s & " "

rs.MoveNext

Wend

s = s & vbCrLf & "

" & vbCrLf

Response.Write s

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

s = ""

For i = Asc("A") to Asc("Z")

s = s & Chr(i)

Next

在第一次迭代中,得到一个字符的字符串

"A"

。在第二次迭代中,VBScript 必须重新分配字符串并复制两个字符

"AB"

s

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

s

,并复制三个字符到

s

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

s

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

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

在该例子中,代码可以改进:字符串的连接将被

Response.Write()

或内嵌脚本 (

) 所替代。如果打开响应缓冲,这个操作将会很快,因为

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

为负数或 0 则禁用缓存。一定要使用较大的负数,例如 -1000 (大于一天),来克服服务器时钟和浏览器时钟之间的差异。第二个属性

Response.ExpiresAbsolute

,允许设置内容过期的指定时间:

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

最后,可以标识内容对 HTTP 代理缓存是否有效,请使用

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 末尾添加斜线,然后服务器将那个目录的默认文档作为响应,或者如果没有默认文档并且目录浏览已被启用,就以目录列表作为响应。添加了斜线便省去了第一个没用的往返。出于对用户的友好,也许想要在显示的名称的末尾省略斜线。

例如,写:

Workshop">http://msdn.microsoft.com/workshop

它还适用于指向在 Web 站点主页的 URL:请使用下面的: ,不要用 .

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

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

从不访问不合格的 Request 对象(例如,

Request("Data")

)。对于不在

Request.Cookies

Request.Form

Request.QueryString

Request.ClientCertificate

中的项,有对

Request.ServerVariables

的隐含调用。

Request.ServerVariables

集合比其他集合慢很多。

责任编辑:admin
相关文章