ASP.NET应用程序性能优化(根据资料归纳整理)

来源:互联网 发布:黎明杀机淘宝多少钱 编辑:程序博客网 时间:2024/04/30 11:26

 影响ASP.NET程序性能的主要原因分析
• 服务器响应时间过长
– 服务器运算量过大
– 页面获取的数据获取时间过长
• 网络传输问题
– 网络传输质量不好
– 传输数据量过大
• 本地系统问题
– 本地硬件配置过低
– 页面具有性能设置缺陷

页面和服务器控件处理

 • 下列准则提供了有效使用ASP.NET 页面和控件的建议

– 避免与服务器间的过多往返行程

– 使用Page.IsPostback 避免往返行程上的额外工作

Page_PreInit-Page_Init- Page_Load— Control events —Page_PreRender —Page_Unload

– 谨慎适当地使用服务器控件

检查您的应用程序代码以确保对ASP.NET服务器控件的使用是必要的。即使它们非常易于使用,但是服务器控件并不总是完
成任务的最佳选择,因为它们会使用服务器资源。在许多情况下,一个简单的呈现或数据绑定代入就可以完成任务。

– 避免过多的服务器控件视图状态

自动视图状态管理是服务器控件的功能,该功能使服务器控件可以在往返过程上重新填充它们的属性值(您不需要
编写任何代码)。但是,因为服务器控件的视图状态在隐藏的窗体字段中往返于服务器,所以该功能确实会对性能产生影响。您应该知道在哪些情况下视图状态会有所帮助,在哪些情况下它影响页的性能。例如,如果您将服务器控件绑定到每个往返过程上的数据,则将用从数据绑定操作获得的新值替换保存的视图状态。在这种情况下,禁用视图状态可以节省处理时间。默认情况下,为所有服务器控件启用视图状态。若要禁用视图状态,请将控件的EnableViewState 属性设置为false

<asp:datagrid EnableViewState="false" datasource="..." runat="server"/>
<%@ Page EnableViewState="false" %>
 

<asp:datagrid EnableViewState="false" datasource="..." runat="server"/>
<%@ Page EnableViewState="false" %>
Page_PreInit Page_Init Page_Load Control events Page_PreRender Page_Unload

状态管理

技巧:

当不需要使用的时候在未使用时禁用会话状态(Session)
– 并不是所有的应用程序或页都需要具体用户的会话状态;您应该在不需要时禁用会话状态
– 如果页需要访问会话变量,但不打算创建或修改它们,则将@Page 指令中的EnableSessionState 属性设置为ReadOnly
– 可以禁用XML Web services 方法的会话状态
– 若要禁用应用程序的会话状态,请在应用程序的Web.config 文件的SessionState 节中将Mode 属性设置为Off
<%@ Page EnableSessionState="false" %>
<sessionState mode="Off" />
[WebMethod(false)]
[WebMethod(EnableSession=false)]

慎重选择会话状态提供程序
– 进程内会话状态
• 迄今为止速度最快的解决方案
• 如果仅在会话状态中存储少量易失数据,则应使用进程内提供程序
– 作为Windows 服务的进程外会话状态
– SQL 数据库中的进程外会话状态
• 用于跨多个处理器或多个计算机缩放应用程序
• 用于当服务器/进程重新启动时不能丢失数据的情况


<sessionState mode="StateServer" stateConnectionString="tcpip=localhost:42424"/>
<sessionState mode="SQLServer" allowCustomSqlDatabase="false"
sqlConnectionString="data source=ben/sql2005;uid=sa"/>
aspnet_regsql.exe -S ben/sql2005 -U sa -ssadd -sstype p
<sessionState mode="InProc"/>

 

数据访问
• 将SQL 存储过程用于数据访问
– 在.NET 框架提供的所有数据访问方法中,基于SQL 的数据访问是生成性能最好的可缩放Web 应用程序的最佳选择
– 使用托管SQL 提供程序时,可通过使用编译的存储过程而不是特殊查询,获得额外的性能提高
• 使用SqlDataReader 获得快进只读数据游标
– SqlDataReader 对象对从SQL 数据库中检索的数据提供前进只读游标
– 在ASP.NET 应用程序中使用只读流,则SqlDataReader 类提供比DataSet 类更高的性能
– SqlDataReader 类使用SQL Server 的本机网络数据传输格式从数据库连接直接读取数据
– SqlDataReader 类实现IEnumerable 接口,该接口也使您可以将数据绑定到服务器控件尽可能缓存数据和页输出
– 在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据
– 通过设计要进行缓存的页和数据请求(特别是在站点中预期将有较大通讯量的区域),可以优化这些页的
性能

页面缓存:

主要有两种方式
– 使用@ OutputCache指令
– 使用页面输出缓存API

使用@OutputCache
• <%@ OutputCache  Duration="#ofseconds" Location="Any |Client | Downstream | Server | None"Shared="True | False"
VaryByControl="controlname"
VaryByCustom="browser | customstring"
VaryByHeader="headers"
VaryByParam="parametername" %>


• Duration
– 页或用户控件进行缓存的时间(以秒计)。在页或用户控件上设置该属性为来自对象的HTTP 响应建立了一个过期策略,并将自动缓存页或用户控件输出。注意该属性是必需的。如果未包含该属性,将出现分析器错误。
• Location
– OutputCacheLocation 枚举值之一。默认值为Any。警告包含在用户控件(.ascx 文件)中的@ OutputCache 指令不支持此属性。
• Shared
– 一个布尔值,确定用户控件输出是否可以由多个页共享。默认值为false。有关详细信息,请参见备注部分。注意包含在ASP.NET 页(.aspx 文
件)中的@ OutputCache 指令不支持此属性。
• VaryByCustom
– 表示自定义输出缓存要求的任意文本。如果赋予该属性的值是browser,缓存将随浏览器名称和主要版本信息的不同而不同。如果输入
了自定义字符串,您必须在应用程序的Global.asax 文件中重写HttpApplication.GetVaryByCustomString方法。

VaryByHeader
– 分号分隔的HTTP 标头列表,用于使输出缓存发生变化。当将该属性设为多标头时,对于每个指定的标头,输出缓存都包含一个请求文档的不同版本。注意设置VaryByHeader 属性在所有HTTP 1.1 缓存中启用缓存项,而不仅限于ASP.NET 缓存。用户控件中的@ OutputCache 指令不支持此属性。
• VaryByParam
– 分号分隔的字符串列表,用于使输出缓存发生变化。默认情况下,这些字符串与用GET 方法属性发送的查询字符串值对应,或与用POST 方法发送的参数对应。当将该属性设置为多参数时,对于每个指定的参数,输出缓存都包含一个请求文档的不同版本。可能的值包括none、* 和任何有效的查询字符串或POST 参数名称。警告在输出缓存ASP.NET 页时,该属性是必需的。它对于用户控件也是必需的,除非已经在用户控件的@ OutputCache 指令中包含了VaryByControl属性。如果没有包含它,则发生分析器错误。如果您不想使缓存内容随任何指定
参数发生变化,请将该值设为none。如果要使输出缓存根据所有参数值发生变化,请将属性设置为*。
• VaryByControl
– 一个分号分隔的字符串列表,用于更改用户控件的输出缓存。这些字符串代表在用户控件中声明的ASP.NET 服务器控件的ID 属性值。注意除非已经包含了VaryByParam 属性,否则在用户控件@ OutputCache 指令中,该属性是必需的。ASP.NET 页中的@ OutputCache 指令不支持该属性。如果将Shared 属性设置为true,则缓存的用户控件输出可以被多个Web 窗体页访问。如果不设置为true,默认行为是为包含用户控件的每一页缓存用户控件输出的一个版本。通过启用Shared 属性,可以潜在地节省大量的内存。
– 注意:
• 不要缓存太多项。

缓存每个项均有开销,特别是在内存使用方面。不要缓存容易重新计算和很少使用的项。其次,给缓存的项分配的有效期不要太短。很快到期的项会导致缓存中不必要的周转,并且经常导致更多的代码清除和垃圾回收工作。若关心此问题,请监视与ASP.NETApplications 性能对象关联的Cache TotalTurnover Rate 性能计数器。高周转率可能说明存在问题,特别是当项在到期前被移除时。这也称作内存压力。
• 给缓存项分配的有效期不要太短

Web 应用程序
• 大型Web 应用程序,请预编译它
– 减少首次访问页时的分析及编译开销
• 必要时调整应用程序每个辅助进程的线程数
– 该结构将根据可用于请求的CPU 功率,来决定允许同时执行的请求数。这项技术称作线程门控
– 使用与“ASP.NET Applications”性能对象关联的“Pipeline Instance
Count”(管线实例计数)性能计数器,可以在Windows 性能监视器中监视线程门控
– 通过更改Machine.config 配置文件processModel 元素(ASP.NET
设置架构)节中的MaxWorkerThreads 和MaxIOThreads 属性,手动设置进程中的线程数限制
– 辅助线程是用来处理ASP.NET 请求的,而IO 线程则是用于为来自文件、数据库或XML Web services 的数据提供服务的
• 对于广泛依赖外部资源的应用程序,请考虑在多处理器计算机上启用网络园艺

• 禁用调试模式
• 优化Web 服务器和特定应用程序的配置文件
– 仅对需要的应用程序启用身份验证
• 默认情况下,ASP.NET 应用程序的身份验证模式为Windows 或集成的NTLM
• 大多数情况下,最好仅对需要身份验证的应用程序在Machine.config 文件中禁用身份验证,并在Web.config 文件中启用身份验证
– 根据适当的请求和响应编码设置来配置应用程
• ASP.NET 默认编码格式为UTF-8
• 如果您的应用程序仅使用ASCII 字符,请配置您的ASCII 应用程序以获得稍许的性能提高
<compilation debug="true">
<globalization requestEncoding="utf-8" responseEncoding="utf-8"/>
<authentication mode="Forms">
<forms name="SDP" loginUrl="login.aspx" protection="All" path="/" >
</authentication>

优化Web 服务器和特定应用程序的配置文件
– 考虑对应用程序禁用AutoEventWireup
• 重写Page 对象的OnLoad 方法,而不是使用Page_Load 方法
– 从请求处理管线中移除不用的模块
<pages autoEventWireup="false"/>

优化技巧和要点

不要依赖代码中的异常
– 因为异常大大地降低性能,所以您不应该将它们用作控制正常程序流程的方式。如果有可能检测到代码中可能导致异常的状态,请执行这种操作。不要在处理该状态之前捕获异常本身。

– 检查空值,分配给将分析为数字值的字符串,在应用数学运算前检查特定值
// This is not recommended.
try {
result = 100 / num;
}
catch (Exception e) {
result = 0;
}
// This is preferred.
if (num != 0)
result = 100 / num;
else
result = 0;

对字符串连接使用Response.Write
– 在页面或用户控件中对字符串连接使用HttpResponse.Write 方法
– 大量字符串连接时不要使用+ ,应使用StringBuilder来构造
Response.Write("a")
Response.Write(myString)
Response.Write("b")
Response.Write(myObj.ToString())
Response.Write("c")
Response.Write(myString2)
Response.Write("d")
string strWrite;
strWrite = "ABC";
strWrite += strTest;
strWrite += …;
StringBuilder sb = new StringBuilder();
sb.Append("ABC");
sb.Append(strTest);

适当地使用公共语言运行库的垃圾回收器和自动内存管理
– 不要对每个请求使用过多内存(如在内存中存储大型对象或数据集),因为这样垃圾回收器将必须更频繁地进行更多的工作
– 当不再需要对象时,请不要在代码中保留不必要的对象引用,因为在它们仍然被引用的情况下,垃圾回收器将无法释放资源
– 尽量避免使用含Finalize 方法的对象,因为它们在后面会导致更多垃圾回收器工作
• 将大量调用的COM 组件移植为托管代码
– 大的性能障碍之一是将数据从非托管环境封送到托管环境
– 在交互操作中,请在任何一端执行尽可能多的任务,然后进行单个调用而不是一系列小调用
– 例如,公共语言运行库中的所有字符串都是Unicode 的,所以应在调用托管代码之前将组件中的所有字符串转换成Unicode 格式

避免单线程单元(STA) COM 组件
– 默认情况下,ASP.NET 不允许STA COM 组件在页内运行
– 若要运行它们,必须在.aspx 文件内将ASPCompat=true 属性包含
在@ Page 指令中
– 如果必须使用STA COM 组件,则应避免在执行期间进行大量调用,并尝试在每次调用期间发送尽可能多的信息
– 免在构造页面期间创建STA COM 组件
<%@ Page Language="VB" ASPCompat="true" %>
<script runat=server>
Dim myComp as new SampleSTAComponent()
Public Sub Page_Load()
myComp.Name = "Sample"
End Sub
</script>
<html>
<%
Response.Write(Server.HtmlEncode(myComp.SayHello))
%>
</html>
<%@ Page Language="VB" ASPCompat="true" %>
<script runat=server>
Dim myComp
Public Sub Page_Load()
myComp = new SampleSTAComponent()
myComp.Name = "Sample"
End Sub
</script>
<html>
<%
Response.Write(Server.HtmlEncode(myComp.SayHello))
%>
</html>

仅对需要的应用程序启用身
份验证
• 默认情况下,身份验证模式为Windows,或集成NTLM。大多数情况下,对于需要
身份验证的应用程序,最好在Machine.config 文件中禁用身份验证,并在Web.config 文件中启用身份验证。

选择适合页面或应用程序的数据查看机制
• 根据您选择在Web 窗体页显示数据的方式,在便利和性能之间常常存在着重要的权衡。例如,DataGrid Web 服务器控件可能是一种显示数据的方便快捷的方法,但就性能而言它的开销常常是最大的。在某些简单的情况下,您通过生成适当的HTML 自己呈现数据可能很有效,但是自定义和浏览器定向会很快抵销所获得的额外功效。
Repeater Web 服务器控件是便利和性能的折衷。它高效、可自定义且可编程。

尽量使用客户端脚本
• 虽然您很可能希望尽量多地使用Web 窗体页框架的那些节省时间和代码的功能,但在某些情况下却不宜使用ASP.NET 服务器控件和回发事件处理。通常,只有在检索或存储数据时,您才需要启动到服务器的往返过程。多数数据操作可在这些往返过程间的客户端上进行。例如,从HTML窗体验证用户输入经常可在数据提交到服务器之前在客户端进行。通常,如果不需要将信息传递到服务器以将其存储在数据库中,那么您不应该编写导致往返过程的代码。

原创粉丝点击