您当前的位置: 首页 > 网站编程 > ASP教程 > 改善ASP性能和外观的技巧集锦

改善ASP性能和外观的技巧集锦

作者:guanchaofeng 来源:本站整理 发布时间: 2009-06-10 22:21 点击:
技巧1:将经常使用的数据缓存在Web服务器上 典型的ASP页从后端数据存储中检索数据,然后将结果转换成超文本标记语言(HTML)。无论数据库的速度如何,从内存中检索数据总要比从后端数据存储中检索数据快得多。从本地硬盘读取数据通常也比从数据库中检索数据更

改善ASP性能和外观的技巧集锦

  技巧1:将经常使用的数据缓存在Web服务器上
  
  典型的ASP页从后端数据存储中检索数据,然后将结果转换成超文本标记语言(HTML)。无论数据库的速度如何,从内存中检索数据总要比从后端数据存储中检索数据快得多。从本地硬盘读取数据通常也比从数据库中检索数据更快。因此,通常可以将数据缓存在Web服务器上(存储在内存或磁盘中),来提高性能。缓存是传统的以空间换取时间的做法。如果您缓存的内容正确,那么您可以看到性能会有显著的提高。为使缓存有效,必须保存那些经常重复使用的数据,且要重新计算这些数据需要(适度)大的开销。如果缓存的都是些陈旧的数据,就会造成内存浪费。不经常发生改变的数据是很好的缓存候选数据,因为您不必担心随着时间的迁移该数据与数据库同步的问题。组合框列表、引用表、DHTML碎片、扩展标记语言(XML)字符串、菜单项和站点配置变量(包括数据源名称(DSN)、Internet协议(IP)地址和Web路径)都是很好的缓存候选内容。注意您可以缓存数据的“表示”,而不缓存数据本身。如果ASP页很少更改,且缓存的开销也很大(例如,整个产品目录),则应考虑事先产生HTML,而不是在响应每个请求时重新显示。应将数据缓存在哪里,有哪些缓存策略?通常,数据缓存在Web服务器的内存或磁盘中。
  
  技巧2:将经常使用的数据缓存在Application或Session对象中
  
  ASPApplication和Session对象为将数据缓存在内存中提供了方便的容器。您可以将数据指派到Application和Session对象中,这些数据在HTTP调用之间保留在内存中。Session数据是按每个用户分别存储的,而Application数据则在所有用户之间共享。什么时候将数据装载到Application或Session中呢?通常,数据是在启动Application或Session时装载。要在Application或Session启动过程中装载数据,应将适当的代码分别添加到Application_OnStart()或Session_OnStart()中。这些函数应在Global.asa中,如果没有,则可以添加这些函数。还可以在第一次需要时装函数应在Global.asa中,如果没有,则可以添加这些函数。还可以在第一次需要时装载该数据。为此,在ASP页中添加一些代码(或编写一个可重复使用的脚本函数),以检查数据是否存在,如果不存在,就装载数据。这是一个传统的性能技术,称为“惰性计算”-在您知道需要某一个值以前不计算该值。例如:可以为所需要的每个数据块编写类似的函数。应以什么格式存储数据?可以存储任何变体类型,因为所有脚本变量都是变体型。例如,您可以存储字符串、整数或数组。通常,您将以这些变量类型之一存储ADO记录集的内容。要从ADO记录集获取数据,您可以手工将数据复制到VBScript变量,一次一个字段。使用一个ADO记录集持久函数GetRows()、GetString()或Save()(ADO2.5),可加快速度且更容易一些。在适当的条件下,可以将ADO记录集本身缓存在Application或Session作用域中。有两个警告:
  
  必须将ADO标记为自由线程
  
  必须使用断开连接的记录集。
  
  如果不能保证满足这两个要求,则不要缓存ADO记录集。在下面的“非敏捷组件”和“不要缓存连接”技巧中,我们将讨论将COM对象存储在Application或Session作用域中的危险性。当您将数据存储在Application或Session作用域时,数据将保留在那里,直到您以编程方式改变它、Session过期或Web应用程序重新启动为止。如果数据需要更新怎么办?要手工强制对Application数据进行更新,您可以访问只有管理员才可访问的ASP页来更新数据。或者,您可以通过函数定期自动刷新数据。下面例子存储带有缓存数据的时间戳,并隔一段时间后刷新数据。Session[/b]或Application对象中缓存大的数组不是一个好的做法。在访问数组的任何元素之前,脚本语言的语法要求必须临时复制整个数组。数组能快速查寻和存储在内存中是邻近的关键数据对。索引一个词典比索引一个数组要慢得多。应针对您的实际情况,选择提供最佳性能的数据结构。
  
  技巧3:将数据和HTML缓存在Web服务器的磁盘上
  
  有时,数据可能太多,无法都缓存在内存中。“太多”只是一个说法,这要看您想消耗多少内存,以及需缓存的项目数和检索这些项目的频率。在任何情况下,如果数据太多多少内存,以及需缓存的项目数和检索这些项目的频率。在任何情况下,如果数据太多而无法都缓存在内存中,则考虑将数据以文本或XML文件缓存在Web服务器的硬盘上。可以同时将数据缓存在磁盘和内存中,为您的站点建立最适宜的缓存策略。注意当测量单个ASP页的性能时,检索磁盘上的数据可能不一定要比从数据库检索数据更快。但缓存会降低数据库和网络上的负载。在高负载的情况下,这样做可大大改善总体吞吐量。当缓存开销很大的查询结果(如多表联接或复合存储过程)或大的结果集时,这是非常有效的。与往常一样,要测试一下几种方案的优劣。ASP和COM提供一些建立基于磁盘的缓存方案的工具。ADO记录集Save()和Open()函数保存和装载磁盘中的记录集。可以使用这些方法重新编写上面Application数据缓存技巧中的代码示例,用文件的Save()代替写到Application对象中的代码。有一些其它组件可以用于文件:
  
  Scripting.FileSystemObject可使您创建、读和写文件。
  
  与InternetExplorer一起提供的Microsoft?XML解析器(MSXML)支持保存和装载XML文档。
  
  LookupTable对象(例如,用在MSN上)是从磁盘装载简单列表的最好选择。最后,应考虑将数据的表示缓存在磁盘上,而不是数据本身。预先转换的HTML可以用.htm或.asp文件存储在磁盘上,超级链接可以直接指向这些文件。可以使用商用工具,如XBuilder,或Microsoft?SQLServer?Internet发布功能将产生HTML的过程自动化。或者,您可以将HTML代码片断放在.asp文件中。还可以使用FileSystemObject从磁盘读取HTML文件,或使用XML尽早转换。
  
  技巧4:避免将非敏捷的组件缓存在Application或Session对象中
  
  尽管将数据缓存在Application或Session对象中是一个好的做法,但缓存COM对象却有严重的陷阱。通常,人们倾向于将经常使用的COM对象缓存到Application或Session对象中。很遗憾,许多COM对象(包括所有以VisualBasic6.0或更低版本ession对象中。很遗憾,许多COM对象(包括所有以VisualBasic6.0或更低版本编写的对象)当存储在Application或Session对象时,会引起严重的瓶颈。具体来讲,当任何不敏捷的组件缓存在Session或Application对象时,将引起性能瓶颈。敏捷的组件是被标记为ThreadingModel=Both的组件,它聚集Free-threadedmarshaler(FTM);或被标记为ThreadingModel=Neutral的组件。(Neutral模型是Windows?2000和COM+的新增模型。)下列组件不是敏捷的:
  
  自由线程的组件(除非它们聚集FTM)。
  
  单元线程组件。
  
  单线程组件。
  
  配置的组件(MicrosoftTransactionServer(MTS)/COM+库和服务器程序包/应用程序)不是敏捷的,除非它们是Neutral线程。单元线程组件和其它非敏捷的组件在页作用域内是最适合的(即,它们在单个ASP页上创建和销毁)。在IIS4.0中,被标记为ThreadingModel=Both的组件被认为是敏捷的。在IIS5.0中,只有这一点还不够。组件必须不仅被标记Both,还必须聚集FTM。有关敏捷性的文章讲述了如何使以ActiveTemplateLibrary编写的C++组件聚集FTM。要注意如果组件缓存界面指针,那么那些指针本身必须是敏捷的,或必须存储在COM共用界面表(GIT)中。如果您不能重新编译Both线程组件以聚集FTM,那么您可以将组件标记为ThreadingModel=Neutral。或者,如果您不想让IIS执行敏捷性检查(因此,您可以允许非敏捷的组件存储在Application或Session作用域中),您可以在配置数据库中将AspTrackThreadingModel设置为True。不建议更改AspTrackThreadingModel。如果您想将以Server.CreateObject创建的非敏捷的组件存储在Application对象中,IIS5.0将出现一个错误。您可以在Global.asa中使用避免这一错误,但不建议这样做,因为这会导致汇集和串行化,关于这一点将在下面讲述。如果您缓存非敏捷的组件会出现什么毛病?缓集和串行化,关于这一点将在下面讲述。如果您缓存非敏捷的组件会出现什么毛病?缓
  
  存在Session对象中的非敏捷的组件将Session锁定于ASP工作者线程。ASP维护一个工作者线程池来处理请求。通常情况下,一个新请求总是由第一个可用的工作者线程来处理。如果Session被锁定于一个线程,那么请求必须等到其相关的线程可用为止。
  
  将非敏捷的组件存储在Application作用域对性能的影响甚至更坏。ASP必须创建一个特殊的线程运行存储在
  
  Application作用域中的非敏捷组件。这会有两个结果:所有调用都必须汇集到此线程,且所有调用都排成长队。“汇集”的意思是参数必须存储在内存的共享区域;执行一个开销很大的到特殊线程的上下文切换;执行组件的方法;将结果汇集到共享区域;执行另一个开销很大的上下文切换,将控制返回到原始的线程。“串行化”意思是指每次只运行一个方法。两个不同的ASP工作者线程不能同时在共享组件上执行多个方法。这样就杜绝了并发性,特别是在多处理器计算机上。更糟的是,所有非敏捷的Application作用域的组件共享一个线程(主机STA),因此串行化的影响甚至更显著。如之奈何?下面是一些一般的规则。如果您使用VisualBasic(6.0)或更早版本编写对象,那么不要将它们缓存在Application或Session对象中。如果您不知道对象的线程模型,不要缓存它。不要缓存非敏捷的对象,而应在每个页面创建和释放它们。对象直接在ASP工作者线程上运行,因此没有汇集或串行化。如果COM对象在IIS服务器上运行,且如果它们不花长时间初始化和删除,性能尚可。注意单线程对象不应该这样使用。小心-VB可创建单线程对象!如果您必须这样使用单线程对象(如MicrosoftExcel电子表格),别指望会有很高的吞吐量。当ADO被标记为自由线程,ADO记录集可以安全地缓存。要将ADO标记为自由线程,使用Makfre15.bat文件,该文件通常位于以安全地缓存。要将ADO标记为自由线程,使用Makfre15.bat文件,该文件通常位于目录\\ProgramFiles\Common\System\ADO中。
  
  警告如果您使用MicrosoftAccess作为数据库,不应将ADO标记为自由线程的。ADO记录集也必须切断连接。一般来说,如果您不能控制站点中的ADO配置,最好不要缓存记录集。词典组件也是敏捷的对象。LookupTable从数据文件中装载其数据,可用于组合框数据和配置信息。DuwamishBooks中的PageCache对象可提供词典语法,CaprockDictionary也可提供。这些对象或其派生对象可以构成有效缓存策略的基础。注意Scripting.Dictionary对象不是敏捷的,不应该存储在Application或Session作用域中。
  
  技巧5:不要将数据库连接缓存在Application或Session对象中
  
  缓存ADO连接通常是很糟糕的策略。如果一个Connection对象存储在Application对象中,并在所有的页面中使用,那么所有页面将争抢这一连接。如果Connection对象存储在ASPSession对象中,那么将为每个用户创建数据库连接。这就会使连接池的优势荡然无存,并给Web服务器和数据库带来不必要的压力。可以不缓存数据库连接,而是在使用ADO的每个ASP页面中创建和删除ADO对象。这是很有效的,因为IIS内嵌了数据库连接池。更准确地说,IIS自动启用OLEDB和ODBC连接池。这就能确保在每个页面上创建和删除连接将是有效的。因为连接的记录集存储一个到数据库连接的引用,所以您不应将连接的记录集缓存在Application或Session对象中。但是,您可以安全地缓存断开连接的记录集,它们不保存到其数据连接的引用。
  
  技巧6:合理地使用Session对象
  
  一秒钟要求几百页面或成千上万用户同时访问的站点,这个技巧对于必须水平扩展的站点(即那些利用多台服务器以处理负载或实现容错的站点)甚至更重要。对于较小的站点,诸如Intranet站点,要想实现Session带来的方便,必然增大系统开销。简言之,ASP自动为每个访问Web服务器的用户创建一个Session。每个Session大约需要10KB的内存开销(最主要的是数据存储在Session中),这就使所有的请求都减慢。在配置的超时时段(通常是20分钟)结束以前,Session一直保留有效。Session的最大的问题不是性能,而是可扩展性。Session不能跨越几台Web服务器,一旦在一台服务器上创建Session,其数据就留在那儿。这就意味着如果您在一个Web服务器群使用Session,您必须设计一个策略,将每个用户请求始终发到用户Session所在的那台服务器上。这被称为将用户“粘”在Web服务器上。如果Web服务器崩溃,被“粘住的”用户将丢失他们的会话状态,因为会话不是粘到磁盘上。实现粘性会话的策略包括硬件和软件解决方案。诸如Windows2000AdvancedServer中的网络负载平衡和Cisco的LocalDirector之类的解决方案都可以实现粘性会话,代价是要损失一定程度的可扩展性。这些解决方案是不完善的。不建议此时部署您自己的软件解决方案(我们过去常常使用ISAPI筛选器和URL转换等等)。Application对象也不跨越多台服务器,如果您必须跨越Web服务器群共享和更新Application数据,您必须使用后端数据库。但是,只读Application数据在Web服务器群中仍是有用的。如果只是因为要增加运行时间只读Application数据在Web服务器群中仍是有用的。如果只是因为要增加运行时间(处理故障转移和服务器维护),大多数关键任务站点至少需部署两台Web服务器。因此,在设计关键任务应用程序时,必须实现“粘性会话”,或干脆避免使用Session,以及任何其它将用户状态存储在单个Web服务器上的状态管理技术。如果您不使用Session,一定要将它们关闭。您可以通过InternetServicesManager,为应用程序执行此操作。如果您决定使用Session,您可以采用一些方法减轻它们对性能的影响。您可以将不需要Session的内容(如帮助屏幕,访问者区域等等)移到另一个关闭了Session的ASP应用程序中。您可以逐页提示ASP,您不再需要该页面上的Session对象,使用以下放在ASP页面最上面的指令:使用这一指令有一个很好的理由是,这些Session在框架集方面存在一个有意思的问题。ASP保证任何时候Session只有一个请求执行。这样就确保如果浏览器为一个用户请求多个页面,一次只有一个ASP请求接触Session,这样就避免了当访问Session对象时发生的多线程问题。很遗憾,一个框架集中的所有页面将以串行方式显示,一个接一个,而不是同时显示。用户可能必须等候很长时间,才能看到所有的框架。该故事的寓意:如果某些框架集页面不依靠Session,一定要使用EnableSessionState=False指令告诉ASP。
  
  有许多管理Session状态的方法,可替代Session对象的使用。对于少量的状态(少于4KB),我们通常建议使用Cookies、QueryString变量和隐式变量。
  
  技巧7:将代码封装在COM对象中
  
  如果您有许多VBScript或JScript,您可以经常将代码移到编译的COM对象中,从而可改善性能。编译的代码通常比解释的代码运行得更快。编译的COM对象可以通过“早绑定”访问其它COM对象,与脚本使用的“晚绑定”相比,“早绑定”是调用COM对象的更有效方法。将代码封装在COM对象中还有一些优点(除性能之外):
  
  COM对象有利于将表示逻辑与业务逻辑分开。
  
  COM对象可以保证代码重复使用。
  
  许多开发人员发现以VB、C++或VisualJ++编写的代码比ASP更容易调试。
  
  COM对象也有缺点,包括初始开发时间和需要不同的程序设计技巧。注意封装少量的ASP可能引起性能下降,而不会得到性能改进。这种情况通常在少量的ASP代码被封装进COM对象时发生。在这种情况下,创建和调用COM对象的系统开销超过了编译的代码的优点。应反复地试验,以确定什么样的ASP脚本和COM对象代码的组合产生最好的性能。注意,与MicrosoftWindowsNT?4.0/IIS4.0相比,Windows2000/IIS5.0中在脚本和ADO性能方面有了很大的改进。因此,随着IIS5.0的推出,编译代码比ASP代码的性能优势有所降低。如果您部署COM组件,以负荷对它们进行测试特别重要。事实上,理所当然应对所有的ASP应用程序进行负荷测试。
  
  技巧8:迟一点获得资源,早一点释放资源
  
  这里是一个小技巧供您参考。一般来说,最好迟一点获得资源,早一点释放资源。这适用于COM对象以及文件句柄和其它资源。这种优化方法主要用于ADO连接和记录集。当您使用完记录集,比方说在显示一个表及其数据之后,应立即释放它,而不是等到页面结束时再释放。将VBScript变量设置为Nothing是最好的做法。不要让记录集超出作用域之外。而且,要释放任何相关的Command或Connection对象(在将记录集或连接设置为=Nothing之前,不要忘记调用Close())。这会缩短数据库必须为您准备资源的时间,并尽快释放数据库到连接池的连接。
  
  技巧9:进程外执行过程以性能换取可靠性
  
  ASP和MTS/COM+两者都有配置选项,可使您兼顾可靠性和性能。当建立和部署应用程序时,应知道如何兼顾两者的性能。ASP选项可以配置ASP应用程序,以便以三种方法之一运行。在IIS5.0中,引入了“隔离级”这一术语以说明这些选项。这三个隔离级分别是低级、中级和高级:
  
  低级隔离:这在IIS的所有版本中都得到支持,且是最快的。它在Inetinfo.exe中运行ASP,Inetinfo.exe是主要IIS进程。如果ASP应用程序崩溃,IIS也会崩溃。(要在IIS4.0下重新启动IIS,Web站点管理员应使用诸如InetMon之类的工具监视站点,如果服务器发生故障,应启用批处理文件以重新启动服务器。IIS5.0引入了可靠的重新启动,该方法可使发生故障的服务器自动重新启动。)
  
  中级隔离:IIS5.0引入了这个新的级别,它被称为进程外级别,因为ASP在IIS进程之外运行。在中级隔离中,被配置作为中级隔离运行的所有ASP应用程序都共享一个进程空间。这就减少了在一台服务器运行多个进程外ASP应用程序所需要的进程数量。中级隔离是IIS5.0中的默认隔离级别。
  
  高级隔离:在IIS4.0和IIS5.0中支持这一级别,高级隔离也是进程外的。如果ASP崩溃,Web服务器并不会崩溃。下次ASP请求时,ASP应用程序就会自动重新启动。在高级隔离中,配置作为高级隔离运行的每个ASP应用程序都在其自有进程空间中运行。这样做可保护ASP应用程序彼此之间不相互干扰。其缺点是它要求每个ASP应用程序都要有一个单独的进程。当在一台服务器上必须运行许多应用程序时,系统开销就会大大增加。
  
  哪个选项最好的呢?在IIS4.0中,进程外运行将显著降低性能。在IIS5.0中,做了许多改进,将进程外运行ASP应用程序所产生的开销降到最低限度。事实上,在绝大多数测试中,IIS5.0中的ASP进程外应用程序比IIS4.0中的进程内应用程序运行得更快。不管怎样,在两个平台上,进程内(低隔离级)性能最佳。但是,如果访问率相对较低或最大吞吐量较低,低隔离级的优势不太明显。因此,在您每一Web服务器每秒钟需要数百或成千上万页面时,才会觉得有必要设置低隔离级。与往常一样,应对多种配置进行测试,确定您要采取哪一种折衷方案。
  
  注意当您运行ASP进程外应用程序时(中级或高级隔离),它们在NT4中的MTS和在Windows2000中的COM+中运行。即,在NT4中它们在Mtx.exe中运行;而在Windows2000中,它们在DllHost.exe中运行。您可以在任务管理器中看到这些进程在运行。您还可以看到IIS如何为进程外ASP应用程序配置MTS程序包或COM+应用程运行。您还可以看到IIS如何为进程外ASP应用程序配置MTS程序包或COM+应用程序。
  
  COM选项
  
  COM组件也有三种配置选项,虽然与ASP选项不完全类似。COM组件可以是“未配置的”、配置为库应用程序或配置为服务器应用程序。“未配置的”意思是指组件没有注册COM+。组件将在调用程序的进程空间运行,那就是说,它们是“进程内的”。库应用程序也是进程内的,但使用COM+的服务,包括安全、事务和上下文支持。服务器应用程序被配置为在它们自有的进程空间内运行。
  
  您可以看到未配置的组件比库应用程序略有一些优势。库应用程序比服务器应用程序的性能优点更大。这是因为库应用程序与ASP在同一进程内运行,而服务器应用程序在它们的自有进程内运行。进程间的调用比进程内调用开销更大。而且,当在进程之间传递诸如记录集之类的数据时,必须在两个进程之间复制所有的数据。
  
  陷阱!当使用COM服务器应用程序时,如果您在ASP和COM之间传递对象,要确保对象执行“按值汇集”或MBV。执行MBV的对象将它们自己从一个进程复制到另一个进程。这比下面一种方法好,采用这种方法时,对象仍在创建者的进程中,另外一个进程反复地调用创建进程以使用该对象。切断连接的ADO记录集将“按值汇集”,连接的记录集则不然。Scripting.Dictionary不执行MBV,且不在进程之间传递。
  
  最后,VB程序员请注意:MBV不通过传递参数ByVal获得。MBV由原始的组件作者执行。怎么办?
  
  如果让我们建议一个兼顾性能与可靠性的合理配置,它们应是如下的配置:
  
  在IIS4.0中,使用ASP低隔离级别,使用MTS服务器程序包。
  
  在IIS5.0上,使用ASP的中隔离级,并使用COM+库应用程序。
  
  这些是非常一般的原则,主机服务公司一般情况下以中或高隔离级运行ASP,而单用途的Web服务器可以以低隔离级运行。衡量各种利弊,并自己决定哪个配置更能符合您的需要。
  
  技巧10:使用显式选项
  
  在.asp文件中应使用OptionExplicit。此指令放在.asp文件的最上面,它强制开发人员声明要使用到的所有变量。许多程序员认为这种方法对于调试应用程序很有帮助,因为这种方法避免了键错变量名和误建新变量的可能性(例如,将MyXMLString=)错写成MyXLMString=...。
  
  更重要的一点也许是,声明的变量比未声明的变量速度更快。由此,脚本在运行时每次用到未声明的变量时,按名称引用它。另一方面,声明的变量是有顺序的,要么以编译时间,要么以运行时间。以后,声明的变量都按此顺序引用。因为OptionExplicit强制变量声明,它能确保声明所有变量,因此访问的速度也很快。
  
  技巧11:在子例程和函数中使用局部变量
  
  局部变量是那些在子例程和函数内声明的变量。在函数或子例程内,局部变量访问比全局变量访问更快。局部变量的使用也会使代码更清晰,因此应尽量使用局部变量。
  
  技巧12:将经常使用的数据复制到脚本变量中
  
  当访问ASP中的COM对象时,应将经常使用的对象数据复制到脚本变量中。这样做可减少COM方法调用,因为COM方法调用与访问脚本变量相比,开销相对较大。当访问Collection和Dictionary对象时,这种技术也会减少开销很大的查找。
  
  一般来说,如果您打算不止一次访问对象数据,那么就应将数据放到脚本变量中。这种优化的主要目标是Request变量(Form和QueryString变量)。例如,您的站点可传递一个名为UserID的QueryString变量。假设此UserID在特定页面上被引用12次。可以无须调用Request(?UserID?)12次,而是在ASP页面最上面将UserID指派到。可以无须调用Request(?UserID?)12次,而是在ASP页面最上面将UserID指派到一个变量。然后在该页面自始至终使用该变量。这样就省去了11次COM方法调用。实际上,访问COM属性或方法的开销并没有那么大。
  
  技巧13:避免重新确定数组的维数
  
  应尽量避免Redim数组。就性能而言,如果计算机的物理内存大小有限,最好将数组的初始维数设置为其最不利的情况-或将维数设置为其最佳的情况,然后再按需要重新确定维数。这并非意味着,如果知道您不需要内存时,就随便分配几兆字节的内存。
  
  下面的代码给您显示使用Dim和Redim不当的情形。
  
  〈%
  
  DimMyArray()
  
  RedimMyArray(2)
  
  MyArray(0)=?hello?
  
  MyArray(1)=?good-bye?
  
  MyArray(2)=?farewell?
  
  ...
  
  'someothercodewhereyouendupneedingmorespacehappens,then...
  
  RedimPreserveMyArray(5)
  
  MyArray(3)=?morestuff?
  
  MyArray(4)=?evenmorestuff?
  
  MyArray(5)=?yetmorestuff?
  
  MyArray(5)=?yetmorestuff?
  
  %〉
  
  最好一开始就将数组的初始大小Dim正确(在本例中,是5)比Redim数组使其更大好得多。您可能浪费一些内存(如果您没有使用所有的元素),但获得的好处是速度变得更快。
  
  技巧14:使用响应缓冲
  
  您可以通过启用“响应缓冲”,将要输出的一整页缓冲起来。这样就将写到浏览器的量减到最少,从而改善总体性能。每个写操作都会产生很大的系统开销(在IIS中以及在通过网络发送的数据量方面),因此写操作越少越好。由于其启动慢且使用Nagling算法(用来减轻网络塞车情况),TCP/IP在发送一些大的数据块时比必须发送许多小的数据块时的效率高得多。
  
  有两个方法启用响应缓冲。
  
  第一种,您可以使用InternetServicesManager为整个应用程序启用响应缓冲。我们建议采用这种方法,在IIS4.0和IIS5.0中默认为新的ASP应用程序启用响应缓冲。
  
  第二种,可以在每个ASP页面的接近顶端的地方加入下面的代码行,从而启用响应缓冲:
  
  〈%Response.Buffer=True%〉
  
  此代码行必须在任何响应数据被写到浏览器之前执行(即,在任何HTML出现在ASP脚本之前以及在使用Response.Cookies集合设置任何Cookies之前)。一般来说,最好为整个应用程序启用响应缓冲。这样,您就不必在每个页面最上面写入上述的代码行。
  
  Response.Flush
  
  关于响应缓冲有一个常见的抱怨,就是用户感觉到ASP页面的响应速度很慢(即使整个响应时间得到改进),因为他们必须等到整个页面生成,然后他们才能看到东西。对于响应时间得到改进),因为他们必须等到整个页面生成,然后他们才能看到东西。对于运行时间长的页面,您可以设置Response.Buffer=False,禁用响应缓冲。但是,一个更好的策略是利用Response.Flush方法。这种方法将ASP转换的所有HTML送到浏览器。例如,在转换1,000行的表的前100行之后,ASP可以调用Response.Flush,强制将转换的结果送到浏览器,这样可使用户在其余的行准备好之前看到头100行。这种技术可以将响应缓冲与浏览器逐渐显示数据完美地结合在一起。(注意在上面的1,000行表的举例中,许多浏览器在它们看到关闭〈/table〉标记之前不会开始显示表。检查您的目标浏览器是否支持。为避免这种情况,将表分成多个具有较少行的表,并在每个表之后调用Response.Flush。较新版本的InternetExplorer在表完全下载之前就开始显示表,如果您指定表列宽,显示速度就会特别快,这样做可避免强制InternetExplorer通过测量每个单元格的内容宽度来计算列宽。)另一个关于响应缓冲的常见的抱怨是,当产生非常大的页面时,将占用许多服务器内存。撇开产生大页面的方法不谈,这种问题也可通过巧妙使用Response.Flush来加以解决。
  
  技巧15:批处理内嵌脚本和Response.Write语句
  
  VBScript语法〈%=expression%〉将“expression”的值写到ASP输出流中。如果响应缓冲未启用,那么执行其中的每一条语句,都会以许多小的数据包通过网络将数据写到浏览器中。这样速度很慢。而且穿插执行少量的脚本和HTML,将引起脚本引擎和HTML之间的切换,从而降低性能。因此,使用下面的技巧:使用Response.Write调用代替捆绑紧密的内嵌表达式。当禁用响应缓冲时,这一技巧的效果特别大。最好启用响应缓冲,然后看批处理Response.Write是否有助于提高性能。
  
  技巧16:如果页面需要很长时间才能完成,那么执行前使用Response.IsClientConnected
  
  如果用户性急,他们可能会在您开始执行他们的请求之前,就会放弃ASP页面。如果他们单击刷新或移到服务器上的另一个页面,在ASP请求队列的末尾就有一个新的请求等候,在队列的中间有一个断开连接的请求。当服务器的负载很高时(因此请求队列就会很长,响应时间也会相应地变长),就会经常发生这种情况,这样只能使情况变得更糟。如果用户不再连接,执行ASP页面(特别是慢的、大的ASP页面)已没有任何意义
  
  。您可以使用Response.IsClientConnected属性检查这一情况。如果它返回False,则应调用Response.End并放弃页的其余部分。事实上,IIS5.0已将这一做法编为程序-每当ASP即将执行新请求时,它就会检查请求在队列中已等候了多长时间。如果已经在那里等候了多于3秒钟,ASP将检查客户机是否仍处于连接状态,如果没有连接已经在那里等候了多于3秒钟,ASP将检查客户机是否仍处于连接状态,如果没有连接,就立即终止请求。您可以在配置数据库中使用AspQueueConnectionTestTime设置将超时时间由3秒调整为其它值。如果页面要花很长时间才能执行完,也可以不时地检查Response.IsClientConnected。当启用了响应缓冲时,最好不时地执行Response.Flush,以用户知道,正在发生什么事。
  
  注意在IIS4.0上,除非先执行了Response.Write,否则Response.IsClientConnected就不能正常工作。如果启用了缓冲,您也必须执行Response.Flush。在IIS5.0上,却没有必要这样做,-Response.IsClientConnected工作正常。在任何情况下,Response.IsClientConnected都会有一些开销,因此只有在一个操作至少要花(比方说)500毫秒(如果您想维持每秒钟数十页的吞吐量,这是一个很长的时间)才使用它。
  
  经验表明,不要每次重复执行紧密循环时都调用它,如显示表的许多行时-每隔二十或五十行调用一次可能比较合适。
  
  技巧17:使用〈OBJECT〉标记例示对象
  
  如果要引用不在所有代码路径(特别是服务器或应用程序作用域的对象)中使用的对象,使用Global.asa中〈objectrunat=serverid=objname〉标记声明它们,而不使用Server.CreateObject方法。Server.CreateObject能立即创建对象。如果以后不再使用该对象,您就浪费了资源。〈objectid=objname〉标记声明objname,但在其方法或属性第一次使用以前,不会创建objname。这又是一个惰性计算的例子。
  
  技巧18:对于ADO和其它组件使用TypeLib声明
  
  当使用ADO时,开发人员经常加入adovbs.txt,以访问ADO的各种常量。在要使用常量的每个页面中必须包含此文件。此常量文件相当大,给每个ASP页面的编译时间和脚技巧18:对于ADO和其它组件使用TypeLib声明本大小增加了许多系统开销。IIS5.0引入了绑定到组件类型库的功能。这可使您引用类型库一次,并将其用在每个ASP页面上。每个页面不会产生编译常量文件的开销,且组件开发人员不必建立VBScript#_include文件以在ASP上使用。要访问ADOTypeLib,将下面一条语句放在Global.asa中。
  
  〈!--METADATANAME=?MicrosoftActiveXDataObjects2.5Library?
  
  TYPE=?TypeLib?UUID=?{00000205-0000-0010-8000-00AA006D2EA4}?--〉
  
  或
  
  〈!--METADATATYPE=?TypeLib?
  
  FILE=?C:\ProgramFiles\CommonFiles\system\ado\msado15.dll?--〉
  
  技巧19:利用浏览器的验证功能
  
  现今的浏览器对一些高级功能如XML、DHTML、Java小程序和远程数据服务提供支持。尽可能使用这些功能。所有这些技术都可以执行客户机端验证和数据缓存,免去了到Web服务器的往返。如果您在运行一个智能浏览器,那么浏览器就能为您进行一些验证(例如,在执行POST之前,检查信用卡校验和是否有效)。尽可能使用这一功能。通过减少客户-服务器之间的往返,可降低Web服务器上的负载,并能减少网络通信量(虽然发送到浏览器的第一个页面可能比较大)以及服务器访问的任何后端资源。此外,用户不必像住常一样读取新页,从而用户的感觉会好一些。这样做并不意味着您可以不进行服务器端验证-您还应始终进行服务器端验证。这可以防止由于某种原因(如黑客,或浏览器不运行客户机端验证例程)客户机产生错误的数据。人们已经进行了大量的工作,开发“独立于浏览器”的HTML。正是由于这种忧虑,开发人员不愿再使用流行的浏览器功能,但这些功能本可以改善性能。对于一些真正的高性能站点,必须关心浏览器“访问”问题,一个好的策略是优化页面,使其适应流行的浏览器。使用浏览器功能组件,可以在ASP中方便地检测到浏览器功能。MicrosoftFrontPage等工具有助于设计适合于浏览器和指定HTML版本的代码。参见WhenisBetterWorse?WeighingtheTechnologyTrade-Offs,以了解更进一步的讨论。
  
  技巧20:避免在循环语句中使用字符串串联
  
  许多人在循环语句中建立一个字符串,如下所示:
  
  s=?〈table〉?&vbCrLf
  
  ForEachfldinrs.Fields
  
  s=s&?〈th〉?&fld.Name&?〈/th〉?
  
  Next
  
  WhileNotrs.EOF
  
  s=s&vbCrLf&?〈tr〉?
  
  ForEachfldinrs.Fields
  
  s=s&?〈td〉?&fld.Value&?〈/td〉?
  
  Next
  
  s=s&?*lt;/tr〉?
  
  rs.MoveNext
  
  Wend
  
  s=s&vbCrLf&?〈/table〉?&vbCrLf
  
  Response.Writes
  
  采用这种方法会出现一些问题。第一个问题是反复串联字符串需要花两次方的时间,更通俗地说,运行这种循环语句所花的时间与记录数乘以字段数所得值的平方成正比。在将ADO记录集转换为HTML表的特定情况下,应考虑使用GetRows或GetString。如果在JScript中串联字符串,特别建议使用+=运算符,即,使用s+=?某字符串?,而不使用s=s+?某字符串?。
  
  技巧21:启用浏览器和代理缓存
  
  在默认情况下,ASP禁止在浏览器和代理中进行缓存。这是有意义的,因为就实质而言ASP页面是动态的,上面有随时间不断变化的潜在信息。如果页面不要求在每个视图上进行刷新,您应启用浏览器和代理缓存。这可使浏览器和代理在一定的时间内使用页面的“缓存”副本,您可以控制时间的长短。缓存可以大大减轻服务器上的负载,缩短用户的等待时间。
  
  哪一种动态页面可作为要缓存的页面呢?
  
  注意,在使用浏览器或代理缓存的情况下,Web服务器上记录的访问次数减少了。如果您想准确地测量所有页面视图或张帖公布,您就不希望使用浏览器和代理缓存。浏览器缓存由HTTP“过期”报头控制,该报头由Web服务器发送给浏览器。ASP提供两个简单的机制发送此报头。要设置页面使其过多少分钟后到期,则应设置Response.Expires属性。
  
  技巧22:尽可能使用Server.Transfer代替Response.Redirect
  
  Response.Redirect让浏览器请求另一个页面。此函数常用来将用户重定向到一个登录Response.Redirect让浏览器请求另一个页面。此函数常用来将用户重定向到一个登录或错误页面。因为重定向强制请求新页面,结果是浏览器必须到Web服务器往返两次,且Web服务器必须多处理一个请求。IIS5.0引入了一个新的函数Server.Transfer,它将执行转移到同一台服务器上的另一个ASP页。这样就避免多余的浏览器-Web-服务器的往返,从而改善了总体系统性能以及缩短了用户的响应时间。检查“重定向”中的“新的方向”,上面应该是Server.Transfer和Server.Execute。
  
  技巧23:在目录URL中使用后斜杠
  
  一个相关的技巧是确保在指向目录的URL中使用后斜杠(/)。如果您省略了后斜杠,浏览器就会向服务器发出请求,只是为了告诉服务器,它在请求目录。浏览器就会发出第二个请求,将斜杠附加到URL后面,只有此后,服务器才能以该目录的默认文档或目录列表(如果没有默认文档且启用了目录浏览的话)响应。附加斜杠可省去第一个、无用的住返。为便于用户阅读,可以省略显示名称中的后斜杠。
  
  技巧24:避免使用服务器变量
  
  访问服务器变量会使Web站点向服务器发出一个特殊请求,并收集所有服务器变量,而不只是您请求的那个变量。这种情况类似于,在发霉的阁楼上,在一个文件夹中查找某个文件。当您想要找那个文件时,您必须去阁楼上,先找到文件夹,然后才能找到这份个文件。当您想要找那个文件时,您必须去阁楼上,先找到文件夹,然后才能找到这份文件。当您请求服务器变量时,发生的情况是一样的-您第一次请求服务器变量时,就会使性能受到影响。后面的对其它服务器变量的请求,则不会对性能产生影响。决不要访问非限定的Request对象(例如,Request("Data"))。对于不在Request.Cookies、Request.Form、Request.QueryString或Request.ClientCertificate中的项目,则隐式调用Request.ServerVariables。Request.ServerVariables集合比其它集合慢得多。
  
  技巧25:升级到最新和最出色的
  
  系统组件是恒定的,我们建议您将它们升级到最新和最好的配置。最好升级到Windows2000(因此,也应升级到IIS5.0、ADO2.5、MSXML2.5、InternetExplorer5.0、VBScript5.1和JScript5.1)。在多处理器计算机上,实施IIS5.0和ADO2.5可显著改善性能。在Windows2000下,ASP可以很好地扩展到四个处理器或更多,而在IIS4.0下,ASP的扩展性不能超出两个处理器。在应用程序中使用的脚本代码和ADO越多,升级到Windows2000之后,性能的改善就会越多。如果目前还不能升级到Windows2000,您可以升级到SQLServer、ADO、VBScript和JScript、MSXML、InternetExplorer和NT4ServicePacks的最新版本。它们均可提高性能和可靠性。
  
  技巧26:优化Web服务器
  
  有多种IIS优化参数可以改善站点性能。例如,对于IIS4.0,我们常常发现,增加ASPProcessorThreadMax参数(参见IIS文档)可以显著改善性能,特别是在倾向于等待后端资源(如数据库)或其它中间产品(如屏幕刷)的站点上。在IIS5.0中,您可能发现启用ASPThreadGating比查找一个AspProcessorThreadMax最佳设置效率更高,这一点现在已为大家所熟知。
  
  最佳的配置设置取决于(其中一些因素)应用程序代码、运行所在的系统硬件和客户机工作负荷。找到最佳设置的唯一方法是进行性能测试.
  
  技巧27:进行性能测试
  
  正如我们在前面已经讲过,性能是一个特征。如果您想要改善站点的性能,那么就制定一个性能目标,然后逐步改进,直到达到目标为止。不要,就不进行任何性能测试。通常,在项目结束时,再作必需的结构调整已经为时太晚,您的客户将为此感到失望。将性能测试作为您日常测试的一部分来进行。可以对单个组件分别进行性能测试,如针对ASP页或COM对象,或将站点作为一个整体来测试。许多人使用单个浏览器请求页面,来测试Web站点的性能。这样做就会给您一个感觉,即站点的响应能力很好,但这样做实际上并不能告诉您在负载条件下站点的性能如何。
  
  一般情况下,要想准确地测试性能,您需要一个专门的测试环境。此环境应包括硬件,其处理器速度、处理器数量、内存、磁盘、网络配置等方面与生产环境的硬件相似。其次,您必须指定客户机的工作负荷:有多少同时的用户,他们发出请求的频率,他们点击页面的类型等等。如果您没有站点实际使用情况的数据,您必须估计一下使用的情况。最后,您需要一个可以模拟预期客户机工作负荷的工具。有了这些工具,您就可以开始回答诸如“如果我有N个同时的用户,那么需要多少服务器?”之类的问题。您还可以找出出现瓶颈的原因,并以此为目标进行优化。

分享到:
本文"改善ASP性能和外观的技巧集锦"由远航站长收集整理而来,仅供大家学习与参考使用。更多网站制作教程尽在远航站长站。
顶一下
(0)
0%
踩一下
(0)
0%
[点击 次] [返回上一页] [打印]
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
关于本站 - 联系我们 - 网站声明 - 友情连接- 网站地图 - 站点地图 - 返回顶部
Copyright © 2007-2013 www.yhzhan.com(远航站长). All Rights Reserved .
远航站长:为中小站长提供最佳的学习与交流平台,提供网页制作与网站编程等各类网站制作教程.
官方QQ:445490277 网站群:26680406 网站备案号:豫ICP备07500620号-4