ASP.NET性能优化之让浏览器缓存动态网页的方法
OutputCache是针对所有访问服务器资源的用户,本篇要介绍的浏览器缓存则是针对单个用户,让浏览器在我们的控制下彻底不持续访问服务器上的动态内容,也就是我们要让浏览器变成我们的缓存机制中的一部分,在某些特定的场景下最大化地提升ASP.NET站点的性能。如果说OutputCache是从广度上提升并发效率,则浏览器缓存是从深度上提升效率。
一:HTTP头简介 1.1浏览器第一次请求 假设我们请求一个URL地址,譬如我服务器上的一个静态页面http://192.168.0.77/luminji2/html/test1.htm,会返回如下的HTTP头信息: HTTP头信息中每个参数的含义这里暂且不表,我们关注和本文论述相关的3个信息: 首先,响应状态200OK,即表示从服务器上抓取数据成功。 其次,Last-Modified:
(注意,这里的Last Modified和Http头中的Last-Modified没有任何关系)。 每种浏览器都会有自己的缓存机制,但是都差不多,这里暂且不表。 1.3如何命中缓存 再次请求刚才的URL,我们得到头信息如下: 可以看到状态变为304 Not Modified了,这相当于是WEB服务器告诉浏览器,请用自己的缓存,不要到我这里来下载正文内容。那么,WEB服务器是根据什么来决定这样告诉浏览器呢? 这里,我们就需要请求头信息中的If-Modified-Since。请求头是浏览器发送给WEB服务器的,一旦包含这个参数,就是浏览器跟WEB服务器说:请查看自从 If-None-Match就是Etag判断模式,跟Last-Modified其实完成的目的是一致的,这里暂且不表。 假设我们修改了文件test1.htm,试想会是什么结果,肯定是200OK。浏览器和WEB服务器之间就是通过这种机制来完成静态网页的缓存。 二:asp.net的浏览器缓存实现 上面我们说的是静态页面的情况,那么aspx页面,也就是动态页面会是怎么样一种情况?现在,我们创建一个动态网页来看一看。先来创建一个最简单的aspx,如下: 复制代码 代码如下: <body> <%=DateTime.Now %> </body> 请求一下,得到的头信息如下: 然后再多次请求一下,我们发现每次都是200OK,并且我们发现头信息中丢了一个很重要的信息,那就是Last-Modified。服务器没有告诉浏览器自己的对象的最后修改日期,那么浏览器就只好每次去服务器重新获取全部数据了。看到这里,我们应该明白了,要让浏览器不去拿数据,动态程序就得想法设法自己添加这个头信息。 好的,现在我们就在ASPX的后台代码中这样来实现一个最简单的头信息添加: 复制代码 代码如下: protected void Page_Load(object sender,EventArgs e) { this.Response.AddHeader("Last-Modified",DateTime.Now.ToString("U",DateTimeFormatInfo.InvariantInfo)); } 添加了头信息后,我们发现再次请求URL后,头信息变为如下: 可以欣喜滴看到,响应头中包含了Last-Modified,而请求头中则包含了If-Modified-Since。 当然,我们仍旧发现,每次请求还是200OK。这是当然了,既然头信息都是ASP.NET在后台添加的,那么我们要返回什么样的响应状态给服务器这段逻辑也得由自己来写。现在,我们假设我们要让浏览器缓存10秒的时长,其完整的代码应该如下: 复制代码 代码如下: protected void Page_Load(object sender,DateTimeFormatInfo.InvariantInfo)); DateTime IfModifiedSince; if (DateTime.TryParse(this.Request.Headers.Get("If-Modified-Since"),out IfModifiedSince)) { if ((DateTime.Now - IfModifiedSince.AddHours(8)).Seconds < 10) { Response.Status = "304 Not Modified"; Response.StatusCode = 304; return; } } //其它 } 经过这次修改后,如果我们在10秒内持续请求该aspx页面,则始终返回304状态,也即浏览器不会去服务器拿正文,只会在本地去读取自己的缓存,这样一来,服务器压力自然就小了。如果我们10秒内不对服务器请求这个页面,则10秒后会返回200OK,即重新到服务器拿页面数据。 现在,用AB来模拟100并发用户进行1000次请求,得到的比较结果如下(注意,为了强化效果,我们在后台需要模拟一些比较耗时的动作,比如读取数据库): 左边是未做缓存的aspx页面,右边是做了缓存的aspx页面,可以看到,吞吐率相差10倍之多。 提示,使用ab进行压力测试的时候,需要加入If-Modified-Since的头信息,命令如下: C:&;ab -n1000 -c100 -H "If-Modified-Since: Friday,09 September 2011 09:35:23 GMT" http://192.168.0.77/luminji2/aspx/test1.aspx 本文代码下载:MvcApplication320110909.rar 三:问题的提出 在上面的说到的浏览器缓存实现中,浏览器通过和WEB服务器的沟通协调机制来确定自己是否需要调用缓存,这意味着动态程序仍旧需要处理来自客户端的请求,如果有一种机制能够让浏览器不需要请求服务器就能够决定是否调用缓存,就能彻底舍去服务器处理这一环节。下一篇将继续阐述这种机制。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 如何获取用户在MVC 5中注册的角色的ID
- 在ASP.NET MVC中使用<%$%>
- asp.net – 在IIS中,existingResponse =“PassThrough”是什
- asp.net – 验证失败后如何防止页面跳转到顶部位置?
- asp.net – Application_Start在工作站上工作正常,部署时不
- asp.net-mvc – ASP.NET中的Response.Write是一个坏主意吗?
- asp.net-mvc-2 – EF CTP5错误:对象名称无效
- asp.net – gzip压缩在Windows Azure网站
- 如何在ASP.NET中动态生成列表项到无序列表?
- asp.net-mvc – 程序集使用System.Web.Http 5.1,它比引用的
- asp.net-mvc – ASP.NET MVC:在另一个动作中获取
- asp.net – Sitecore – System.Security.Crypto
- asp.net – WebApi:将参数映射到标头值
- Worker Service in ASP .NET Core
- asp.net-mvc – 防止Google分析在开发环境ASP.NE
- asp.net – SQL Server应用程序角色,性能命中
- asp.net-core – 丰富Serlilogs,每个hangfire工作
- 您能以编程方式更改ASP.NET中的会话超时吗?
- 在子文件夹中运行MVC的Asp.net WebForms应用程序
- asp.net-mvc – 当前上下文中不存在’HttpClient