找回密码
 立即注册
首页 业界区 业界 ASP.NET页面优化,性能提升8倍的方法

ASP.NET页面优化,性能提升8倍的方法

翱龟墓 2025-5-29 16:10:03
今天与大家分享:一种优化页面执行速度的方法。
采用这个方法,可以使用页面的执行速度获得【8倍】的提升效果。
为了让您对优化的效果有个直观的了解,我准备了下面的测试结果截图:
1.png

测试环境:
1. Windows Server 2003 SP2
2. Viaual Studio 2008,使用自带的WebDev.WebServer.EXE运行网站程序。
3. (ThinkPad SL510):Core2 T6670 2.2GHz, 4G内存
二个红框中的数字反映了优化前后的执行时间。
数字表明:优化前后,执行时间有了8倍多的差别。
本文的测试结果也仅仅只是一个参考数字,这个结果也只是根据我所设计的测试页面得出的。
优化的过程中,如果不使用服务器控件,那么给GC减少的压力其实也是无法测试到的。
在测试过程中,我还发现测试结果并不是很稳定,因此截图具有一定的偶然性。
测试页面或许在某些方面存在一些片面性,因此,结果仅供参考。
测试背景

看过了优化结果,再来介绍一下:这个测试到底是在测试什么东西?
现在有很多做ASP.NET的开发人员,应该都是从ASP.NET的WebForm编程模型开始学习的。大家都很喜欢用服务器控件,不管输出什么,都会使用服务器控件。有时候为了让页面呈现干净的HTML代码,有些人会选择使用Repeater,Literal这类简单的服务器控件。或许有些人认为:我已不使用GridView这样强大复杂的控件,页面执行速度已经很快了。
真是这样吗?
今天测试的起点就从使用简单的服务器开始,我会分二次对它做一系列的性能优化。
最终就是上图中的3个结果,它们反映了二次优化的改进过程。

在继续介绍之前,有一点我想有必要说明一下:
优化的过程涉及到ASP.NET服务器控件的使用,测试结果也仅仅只是一个参考数字。
如果您认为您的开发工作非常依赖于服务器控件的使用,
那么测试结果对您来说其实是无意义的,请不要在意这个结果。

测试方法

在这次优化过程中,我并没有设计很复杂的测试页面,而是一个很简单的测试页面,页面显示效果如下:
2.png

这个页面其实就是显示了一堆超链接,它们来自于我的博客侧边栏的【推荐排行榜】,总共有20条记录,我让页面重复5次输出,也就是生成了100个超链接。
测试的数据是这样获取的:
我复制了我的博客侧边栏的【推荐排行榜】的那段HTML代码,保存到一个文件中:
3.png

然后,网站在初始化时,从这段HTML代码提取链接地址以及显示文字,保存到一个BlogInfo的列表中,代码如下:
  1. public class BlogInfo
  2. {
  3.     public string Title;
  4.     public string Href;
  5. }
  6. public static class XmlDb
  7. {
  8.     public static List<BlogInfo> Blogs { get; private set; }
  9.     public static void LoadBlogs()
  10.     {
  11.         string filePath = Path.Combine(HttpRuntime.AppDomainAppPath, @"App_Data\RecommendList.html");
  12.         XElement html = XElement.Parse(System.IO.File.ReadAllText(filePath));
  13.         Blogs =
  14.             (from a in html.Elements("li").Elements("a")
  15.              select new BlogInfo { Title = a.Value, Href = a.Attribute("href").Value }).ToList();
  16.     }
  17. }
复制代码
测试时,就把XmlDb.Blogs的内容显示在网页中。
我想这个测试还是比较接近于现实开发的。
这里又有一个问题:我如何测试页面的执行速度?
虽然说创建HttpWebRequest访问页面是个很简单的方法,但我并不打算这样做。
因为从HttpWebRequest发起调用到获取结果,这其中除了有页面的执行时间,还混杂较多的额外调用开销。最终,我选择了在一次HTTP请求中,循环调用Server.Execute来执行页面,并统计时间的方式。其实如何选择测试方法,对于二个测试对象还说,都是公平的。只是说:尽量减少一些额外的调用开销,会让测试结果的差异更大,也更明显。
说明:为了测试代码写起来简单,我使用了MyMVC框架
测试用例1:WebFromPage.aspx

前面介绍了测试背景以及测试方法。现在就来介绍第1个测试用例,它采用了WebForm编程模型中最经典的写法。
页面代码:
  1. <%@ Page Language="C#" CodeFile="WebFromPage.aspx.cs" Inherits="TestPage_WebFromPage" %>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <title>PagePerformanceTest   http://www.cnblogs.com/fish-li/</title>
  5. </head>
  6. <body>
  7. <p>This is WebFromPage.aspx</p>
  8. <ItemTemplate>
  9.     </asp:HyperLink><br />
  10. </ItemTemplate>
  11. <FooterTemplate><hr /></FooterTemplate>
  12. </asp:Repeater>
  13. <ItemTemplate>
  14.     </asp:HyperLink><br />
  15. </ItemTemplate>
  16. <FooterTemplate><hr /></FooterTemplate>
  17. </asp:Repeater>
  18. <ItemTemplate>
  19.     </asp:HyperLink><br />
  20. </ItemTemplate>
  21. <FooterTemplate><hr /></FooterTemplate>
  22. </asp:Repeater>
  23. <ItemTemplate>
  24.     </asp:HyperLink><br />
  25. </ItemTemplate>
  26. <FooterTemplate><hr /></FooterTemplate>
  27. </asp:Repeater>
  28. <ItemTemplate>
  29.     </asp:HyperLink><br />
  30. </ItemTemplate>
  31. <FooterTemplate><hr /></FooterTemplate>
  32. </asp:Repeater>
  33. </body>
  34. </html>
复制代码
页面的CodeFile代码:
  1. public partial class TestPage_WebFromPage : System.Web.UI.Page
  2. {
  3.     protected override void OnLoad(EventArgs e)
  4.     {
  5.         base.OnLoad(e);
  6.         repeater1.DataSource = XmlDb.Blogs;
  7.         repeater1.DataBind();
  8.         repeater2.DataSource = XmlDb.Blogs;
  9.         repeater2.DataBind();
  10.         repeater3.DataSource = XmlDb.Blogs;
  11.         repeater3.DataBind();
  12.         repeater4.DataSource = XmlDb.Blogs;
  13.         repeater4.DataBind();
  14.         repeater5.DataSource = XmlDb.Blogs;
  15.         repeater5.DataBind();
  16.     }
  17.     protected void repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
  18.     {
  19.         if( e.Item.ItemType == ListItemType.Item ) {
  20.             BlogInfo blog = e.Item.DataItem as BlogInfo;
  21.             HyperLink link1 = e.Item.FindControl("link1") as HyperLink;
  22.             link1.NavigateUrl = blog.Href;
  23.             link1.Text = blog.Title;
  24.         }
  25.     }
  26. }
复制代码
测试代码:
  1. [Action]
  2. public object Test1(string callTimes)
  3. {
  4.     int count = 0;
  5.     int.TryParse(callTimes, out count);
  6.     if( count <= 0 )
  7.         return count;
  8.     HttpContext context = HttpContext.Current;
  9.    
  10.     // 先执行一次,排除编译时间
  11.     string html = MyMVC.PageExecutor.Render(context, "/TestPage/WebFromPage.aspx", null);
  12.     Stopwatch watch = Stopwatch.StartNew();
  13.     for( int i = 0; i < count; i++ )
  14.         html = MyMVC.PageExecutor.Render(context, "/TestPage/WebFromPage.aspx", null);
  15.     watch.Stop();
  16.     return watch.Elapsed.ToString();
  17. }
复制代码
测试代码:
[code][Action]public object Test2(string callTimes){    int count = 0;    int.TryParse(callTimes, out count);    if( count
您需要登录后才可以回帖 登录 | 立即注册