如何提高ASP.NET性能
如果您在ASP.NET中编写的代码,那么你需要通过以下几点,以确保良好的性能:
- 你是否使用缓存吗?
- 你是否使用会话状态?
- 你使用的应用程序状态吗?
- 你使用线程和同步功能?
- 你资源的有效管理呢?
- 你有效地管理字符串?
- 你有效地管理例外?
- 有你优化你的网页?
- 你使用视图状态?
- 你使用服务器控件吗?
- 你从你的页面访问数据吗?
- 你可以使用数据绑定吗?
- 你从ASPX页面调用非托管代码?
- 你有没有审查Machine.config中的设置吗?
您使用缓存吗?
使用下面的复习题,以评估您的代码使用ASP.NET缓存功能:
- 你有太多的变化输出缓存吗?
检查您的网页,使用输出缓存,以确保数量变化有限制。输出缓存页面太多的变化可以导致内存使用量的增加。您可以识别的网页,使用搜索字符串“OutputCache”输出缓存。
- 你能使用输出缓存?
在审查您的网页时,开始问自己:如果可以缓存整个页面 。如果整个页面不能被缓存,可以把它的部分被缓存?即使数据不是一成不变的,可以考虑使用输出缓存 。如果您的内容并不需要在近实时传送,考虑输出缓存。
使用输出缓存缓存,无论是整个页面或部分页面可以显著提高性能 。 - 有,将更好地存储在缓存中的静态数据?
识别应用程序端的数据是静态的还是很少更新。这种类型的数据存储在缓存中的一个伟大的候选人。
- 你访问缓存中的项目为空值之前检查吗?
前检查null访问缓存的项目,如下面的代码片段所示,您可以提高性能。
Object item = Cache["myitem"];
if (item==null)
{
// repopulate the cache
}Object item = Cache["myitem"];
if (item==null)
{
// repopulate the cache这有助于避免任何导致的异常空对象。为了找到你的代码在您访问缓存。
您使用会话状态?
使用下面的复习题,审查代码的使用会话状态:
- 你不需要时禁用会话状态?
默认情况下,会话状态仍然。如果您的应用程序不使用会话状态,禁用它在Web.config文件如下:
<sessionstate mode="Off" />如果您的应用程序的某些部分需要会话状态,确定不使用它,这些页面禁用它通过使用下面的页面级别属性的页面。
- 最大限度地减少使用的会话状态,增加了应用程序的性能。
- 你有页面不写一个会话吗?
使用会话状态的页面请求在内部使用ReaderWriterLock,管理会话状态的访问。对于只读会话数据的网页,,考虑的EnableSessionState设置为ReadOnly。
<%@ Page EnableSessionState="ReadOnly" . . .%>这是特别有用,当您使用HTML框架。默认设置(由于ReaderWriterLock)页面执行序列化。将它设置为只读,可以防止阻塞和允许更多的并行。
- 你检查之前在会话状态的访问中的项目为空值?
为空,然后再访问该项目的检查,在下面的代码所示,您可以提高性能。
object item = Session["myitem"];
if(item==null)
{
// do something else
}常见的错误,从会话状态中检索数据时是不检查,如果数据是空的,前访问,然后捕获由此导致的异常。你应该避免这种情况,因为异常是昂贵的。要找到你的代码访问会话状态,你可以搜索字符串“会议”。
- 你复杂的对象存储在会话状态吗?
避免复杂的对象存储在会话状态,特别是如果你使用一个彻头彻尾的进程外会话状态存储。当使用进程外会话状态,对象被序列化和反序列化的每个请求,从而降低性能。
- 你STA COM对象存储在会话状态吗?
存储在会话状态中的单线程单元(STA)COM对象会导致线程关联,因为会话绑定到原来的线程上创建该组件。这严重影响性能和可扩展性。确保您使用以下页面级别属性在任何网页上,STA COM对象存储在会话状态。
这力量运行页面的STA线程池,避免任何昂贵的公寓开关从默认的多线程单元(MTA)为ASP.NET线程池。在可能的情况下,避免使用STA COM对象。
你使用应用程序状态吗?
使用下面的复习题,如何有效地评估你的代码使用应用程序状态:
- 你STA COM组件存储在应用程序的状态?
避免STA COM组件存储在应用程序的状态在可能的情况下。这样做有效地瓶颈您的应用程序到一个单独的执行线程访问组件时。在可能的情况下,应避免使用STA COM对象。
- 你使用的应用程序状态字典吗?
用于存储只读的值可以设置在应用程序初始化时,不改变之后,你应该使用的应用程序的状态字典。要知道在代码中使用时,应用程序的状态,如以下几个问题:
- 分配到应用程序变量的存储的内存没有被释放,除非它们被取出或更换。
- 应用程序状态不是Web场或Web园 - 共享存储在应用程序状态中的变量是全球性的的特定应用程序运行过程中,。每个应用程序进程可以有不同的价值观。
- 考虑使用以下替代应用程序的状态:
- 为应用程序而不是使用状态字典创建的静态属性。它是更有效的访问状态字典查找比一个静态属性。例如,考虑下面的代码:
Application["name"] = "App Name";
这是更有效地使用下面的代码:
private static String _appName = "App Name";
public string AppName
{
get{return _appName;}
set{_appName = value;}
} - 使用配置文件,用于存储应用程序的配置信息。
- 考虑缓存数据是足够的挥发性,它不能存储在应用程序的状态,但需要定期更新缓存中的对象,从一个持久化介质。
- 使用会话存储用户特定的信息。你可以找出你的代码的地方使用搜索字符串“应用”应用程序的状态。
- 为应用程序而不是使用状态字典创建的静态属性。它是更有效的访问状态字典查找比一个静态属性。例如,考虑下面的代码:
你使用应用程序状态吗?
的。NET Framework公开各种线程和同步功能,您的代码中使用多线程的方式可以有一个应用程序的性能和可扩展性的显著影响。使用下面的复习题,到如何有效地评估你的ASP.NET代码使用线程:
- 你创建线程每个请求的基础上?
避免手动创建ASP.NET应用程序中的线程。创建线程是一项昂贵的的操作,需要初始化托管和非托管的资源。如果你需要额外的线程来执行工作,使用CLR线程池。为了找到你的代码的地方,你正在创建线程,搜索字符串“的ThreadStart”。
- 你执行长时间运行的阻塞操作吗?
避免堵在你的ASP.NET应用程序在可能的情况下操作。如果你必须执行一个长时间运行的任务,然后再考虑使用异步执行(如果你可以自由调用线程)或使用异步“火,忘记”模型。
资源的有效管理呢?
使用以下的检讨,以评估您的代码如何有效地使用资源的问题:
- 你明确地关闭资源?
确保您的代码明确关闭对象实现IDisposable接口通过调用对象的Dispose或Close方法。未能关闭资源和迅速,可导致内存消耗增加,表现不佳。
没有关闭数据库连接,是一个普遍问题。使用finally块(或在C#中使用的块)来释放这些资源,以确保资源被关闭,即使发生异常。
- 池共享资源呢?
检查您使用池访问共享资源时,以提高性能。确保共享资源,如数据库连接和服务组件,可以汇集,正在汇集。没有集中,你的代码即被初始化的开销每个共享资源的使用时间。
- 你晚获取资源和早期释放他们?
打开共享资源之前,你需要他们,只要你完成他们释放。持有时间比你需要的人士,到资源,增加内存的压力,并增加对这些资源的竞争,如果他们共享。
- 你块数据传输I / O调用吗?
如果你需要在块I / O调用的数据传输,分配和针块用于发送和接收缓冲区。如果您需要进行并发的I / O调用,你应该创建一个固定的回收这是在不同的客户,而不是每个请求的基础上创建一个缓冲区的缓冲区池。这可以帮助您避免堆碎片和减少缓冲区的创建时间。
您有效地管理弦乐?
使用下面的复习题,以评估如何有效地你的ASP.NET代码操纵字符串:
- 你使用的格式化输出的Response.Write吗?
确定你的代码在您连接输出,如创建一个表,并考虑使用Response.Write来代替。回复于书面内容给客户端的最有效的方法。
- 你使用StringBuilder来连接字符串吗?
如果追加数量是未知的,你不能发送数据到客户端使用的Response.Write立即的,使用StringBuilder类来连接字符串。
- 你=连接字符串+吗?
确定在你的代码的地方,你使用+ =运算符执行字符串串联。如果追加的数量是未知的,或你追加一个未知大小的数据,考虑使用StringBuilder类来代替。
您有效地管理例外?
使用以下审查问题,如何有效地评估您的代码中使用异常:
- 有你在Global.asax中实现了一个错误处理程序?
虽然落实在Global.asax中的错误处理程序不一定提高性能,它可以帮助您确定您的应用程序,在发生意外异常。您找出发生的异常后,采取适当的行动,以避免这些例外。
- 你使用的try /可支配资源终于?
确保在finally块中释放,以确保他们得到清除,即使在异常事件,可支配资源。不处置的资源,是一个普遍问题。
- 请问你的代码,避免异常?
你的代码应该试图避免例外,以提高性能,因为异常会导致显著的开销。使用以下方法:
- 检查空值。
- 不要使用异常来控制常规应用程序逻辑。
- 不要捕获异常,你不能处理和模糊有用的诊断信息。
- 使用重载Server.Transfer方法Server.Transfer的(字符串,BOOL),而不是Server.Transfer的,Response.Redirect,Response.End,以避免异常。
您优化您的网页?
使用下面的复习题,评估aspx页的效率。
- 你采取的步骤,以减少页面大小?
尽量保持页面大小到最低限度。较大的页大小,因为增加的处理能力和网络带宽利用率,从而可能导致网络拥塞的显著增加CPU的负载增加。这两个因素导致响应时间增加为客户。考虑以下的指引,以协助减少页面大小:
- 包括使用脚本(脚本,而不是点缀的HTML代码标签)。
- 从你的HTML中删除多余的空白字符。
- 禁用它不需要服务器控件的视图状态。
- 避免长时间的控制名称。
- 最小化使用的图形,并使用压缩图像。
- 考虑使用级联样式表,以避免反复相同的格式指令发送到客户端。
- 缓冲禁用?
确保你有缓冲启用。缓冲会导致服务器缓冲输出和发送后,才完成了处理页面。如果缓冲被禁止,劳动者的过程,需要不断流从所有的并发请求的响应,这可能是内存和处理器上的显著的开销,尤其是当你使用ASP.NET进程模型。要找出缓冲禁用,如果你有,你可以搜索以下字符串为您的代码库:“缓冲区”和“BufferOutput。”确保缓冲区<pages>元素属性设置为true,在您的应用程序的Web.config 文件。
<pages buffer="True"> - 你使用Response.Redirect吗?
搜索你的代码为“Response.Redirect”,并考虑更换与Server.Transfer的。这并不招致了一个新的请求成本,因为它避免了任何客户端重定向。
你不能总是简单地取代Response.Redirect调用Server.Transfer的调用,因为Server.Transfer使用一个新的处理程序在执行的处理程序阶段。Response.Redirect产生第二个请求。如果你需要不同的身份验证和授权,缓存,或其他运行时设备上的目标,这两个机制是不等价的。Response.Redirect导致一个额外的请求被发送到服务器。Response.Redirect也使得用户可见的网址。这可能需要在某些情况下,您要求用户书签的新位置。
- 你使用Page.IsPostBack?
检查在你的页面的逻辑使用Page.IsPostBack属性,以减少多余的处理,避免不必要的初始化成本。使用Page.IsPostBack属性有条件地执行代码,根据页面是否是响应服务器控件事件生成,或者它是否是首次加载。
- 你验证用户输入?
检查,验证用户输入客户端上,以减少服务器的往返行程。这也提供了更好的反馈给用户。出于安全原因,确保任何客户端验证与对应的服务器端验证赞扬。
- 你有没有制定明确和严格的真实?
确保您使用Option Strict和明确,以减少意外的后期绑定,当使用Visual Basic。NET中。
<%@ Page Language="VB" Explicit="true" Strict="true" %>这可以很容易地搜索,使用正则表达式的Findstr.exe进行文件。
C:findstr /i /s /r /c:"<%.*@.*page.*%>" *.aspx
pagdefault.aspx:<%@ Page Language="VB" %>
paglogin.aspx:<%@ page Language="VB" %>
pagmain.aspx:<%@ Page Language="VB" Explicit="true" Strict="true" %>
... - 您已禁用调试?
检查你的Web.config文件,并确保调试设置为false <compilation>节和检查。aspx页,以确保调试设置为false。如果启用了调试,编译器不生成优化的代码和页面批次编译。您可以通过使用正则表达式的Findstr.exe进行文件。aspx页。
C:pag>findstr /i /r /c:"<%.*@.*page.*debug=.*true*.*%>" *.aspx
login.aspx:<%@ page Language="VB" Debug="True" %>
main.aspx:<%@ Page Language="c#" Debug="True" %> - 您已禁用跟踪?
检查您的Web.config文件,以确保在<trace>部分禁用跟踪。另外,请检查你的。aspx页,以确保跟踪设置为false。您可以通过使用正则表达式的Findstr.exe进行文件。aspx页。
C:pag>findstr /i /r /c:"<%.*@.*page.*trace=.*true*.*%>" *.aspx
login.aspx:<%@ page Language="VB" Trace="True" %>
main.aspx:<%@ Page Language="c#" Trace="True" %> - 你积极的超时吗?
设置超时积极相应调整。评估每一页,并确定一个合理的超时。默认页是在Machine.config执行超时属性指定超时90秒。服务器资源举行,直到请求被处理完全或执行时间,以较早者为准。在大多数情况下,用户不必等待这样一个长时间才能完成的请求。他们要么完全放弃请求,或发送一个新的请求,这进一步增加了服务器上的负载。
您使用视图状态?
使用下面的复习题,以评估您的应用程序如何有效地使用视图状态:
- 你禁用视图状态时,它不需要?
每一页的评估,以确定是否需要查看状态启用。视图状态会增加开销每个请求。开销包括增加页面发送到客户端,以及一个序列化和反序列化成本的大小。你不需要查看在下列条件下的状态:
- 页面不回自己的页面仅用于输出和不依赖于响应处理。
- 你的页面的服务器控件不处理事件,你有没有动态的或数据绑定的属性值(或他们是在每个请求的代码)。
- 如果你忽略的旧数据,并重新填充的服务器控制每次刷新页面。
- 您已经采取步骤,以减少您的视图状态的大小吗?
评估每一页的视图状态的使用。要确定一个页面的视图状态的大小,您可以启用跟踪,看看每个每个控制如何使用它。控制控制的基础上,禁用视图状态。
你使用服务器控件吗?
使用下面的复习题,检讨如何有效地你的ASP.NET应用程序使用服务器控件:
- 你使用服务器控件时,你不需要吗?
评估您的服务器控件的使用,以确定是否可以替换他们具有重量轻HTML控件或可能是静态的文本。你也许可以在下列情况下更换一个服务器控件:
- 在控制显示的数据是静态的,例如,一个标签。
- 你并不需要以编程方式访问在服务器端控制。
- 控制显示的是只读数据。
- 在回处理过程中不需要控制。
- 你有服务器控制的深层次吗?
服务器控件嵌套很深的层次复合的建设控制树成本。考虑呈现的内容自己使用Response.Write或建立一个自定义的控制,并呈现。要确定的控制和控制层次,使页面的跟踪。
您从您的ASPX页面访问数据吗?
大多数ASP.NET应用程序需要某种形式的数据访问。数据访问的性能和可扩展性问题发现一个共同的地方。审查以下问题,以帮助改善您的应用程序的页面级别的数据访问:
- 你页大的结果集?
确定您的应用程序领域,大的结果集显示和考虑分页的结果。大的结果集显示给用户,可以对性能有显著影响。
- 你使用数据集时,你可以使用DataReaders吗?
- 如果你不需要缓存数据,层与层之间或数据的交换数据绑定到一个控制和只需要只进,只读访问数据,然后使用DataReader,而不是。
您可以使用数据绑定吗?
使用下面的复习题,审查代码的数据绑定使用:
- 你用的Page.DataBind吗?
避免调用的Page.DataBind和单独的每个控件绑定优化您的数据绑定。调用的Page.DataBind递归调用上的每个页面上的控件的DataBind。
- 你使用的DataBinder.Eval吗?
DataBinder.Eval的使用反射,从而影响性能。在大多数情况下,DataBinder.Eval的被称为从一个页面内多次,因此,实施替代方法提供了一个很好的机会,以提高性能。
避免以下做法:
<itemtemplate>
<table><tbody><tr>
<td><%# DataBinder.Eval(Container.DataItem,"field1") %></td>
<td><%# DataBinder.Eval(Container.DataItem,"field2") %></td>
</tr></tbody></table>
</itemtemplate>使用显式转换。它提供了更好的性能,避免反射的成本。投作为一个DataRowView Container.DataItem,如果数据源是DataSet。
<itemtemplate>
<table><tbody><tr>
<td><%# ((DataRowView)Container.DataItem)["field1"] %></td>
<td><%# ((DataRowView)Container.DataItem)["field2"] %></td>
</tr></tbody></table>
</itemtemplate>投作为一个String Container.DataItem如果数据源是一个数组或一个ArrayList。
<itemtemplate>
<table><tbody><tr>
<td><%# ((String)Container.DataItem)["field1"] %></td>
<td><%# ((String)Container.DataItem)["field2"] %></td>
</tr></tbody></table>
</itemtemplate>
aspx页面调用非托管代码吗?
使用下面的复习题,审查代码的互操作性使用:
- 你有没有启用调用STA COM组件ASPCOMPAT吗?
确保任何页面调用STA COM组件ASPCOMPAT页面级别属性设置。这将指示ASP.NET使用STA线程池线程来执行当前页面的请求。默认情况下,ASP.NET使用MTA线程池来处理页面请求。如果您正在使用STA元件,组件绑定到创建的线程。这将导致一个从线程池中的线程STA对象是创建的线程昂贵的线程切换。
- 你创建STA COM组件在页面的构造?
检查您的网页,以确保您没有创建STA COM组件在页面的构造。创建STA组件中的Page_Load,Page_Init或其他事件,而不是。页面的构造函数总是一个MTA线程上执行。当STA COM组件是从一个MTA线程创建,创建STA COM组件在主机上的STA线程。在同一个线程(主机STA)执行单元线程组件从MTA线程创建的所有实例。这意味着,即使所有的用户都有他们自己的COM组件实例的引用,所有到这些组件的调用序列化这一个线程,并在同一时间只有一个呼叫执行。这将有效地瓶颈一个单独的线程的页面,并造成重大的性能下降。如果您使用的是AspCompat属性,这些事件运行一个线程使用STA线程池,它在一个较小的性能结果击中由于线程切换。
- 你用Server.Create对象吗?
避免使用Server.CreateObject和早期绑定到您的组件在编译时尽可能。Server.CreateObject的使用后期绑定,主要是为了向后兼容提供。搜索您的代码库,看看是否使用这个例程,作为替代,创建互操作程序集,利用早期绑定的优势。
你有没有审查Machine.config中的设置吗?
使用下面的复习题,审查您的应用程序的部署计划:
- 调整适当的线程池?
CLR线程池调整适当的调整,提高了性能显著。在部署应用程序之前,确保该线程池已调整为您的应用程序。
- 适当配置的内存限制?
配置ASP.NET内存限制,确保最佳的ASP.NET缓存的性能和服务器的稳定性。在IIS 5.0中,或者当您使用在IIS 6.0的ASP.NET进程模型,配置Machine.config中的内存限制。在IIS 6.0中,您使用IIS MMC管理单元中配置的内存限制。
- 你删除不必要的HttpModules?
包括的HttpModules,你不需要添加额外的开销ASP.NET请求处理。检查您已删除或注释掉在未使用的HttpModules 的Machine.config。