本文内容
- 概述
- 测试用例
- 用 HttpWatch 演示几种刷新界面的区别
- 参考资料
概述
当我们初次访问一个页面后,刷新该页面的方式有很多,包括 F5、Ctl-R、Ctl-F5 和 直接在地址栏按回车(如下图所示)。这几个方式是不同的。
测试用例
本文测试用例使用 Ext.Net_在程序集中自定义 TreePanel 控件 中的演示。
用 HttpWatch 演示几种刷新界面的区别
为保证测试准确性,先用 HttpWatch 清除浏览器缓存,如图1所示:
图1 用 HttpWatch 清除浏览器缓存
初次访问 Default.aspx 页面后,分别以四种方式请求该页面,结果如下所示:
图2 用四种方式请求 Default.aspx 页面——初次请求、F5、Ctl-R、Ctl-F5、地址栏回车
从上到下分别是:
- 初次访问
- F5、
- Ctl-R、
- Ctl-F5
- 直接在地址栏按回车
说明:
- “初次访问”时,HTTP 状态码返回 200;
- 用 F5 和 Ctl-R 刷新界面时,页面资源 HTTP 状态码返回 200;除了 tip-sprite.gif 是从缓存获得外,其他资源的 HTTP 状态码均返回 304。F5 和 Ctl-R 刷新界面相同;
- 用 Ctl-F5 刷新界面时,除了 tip-sprite.gif 是从缓存获得外,所有资源的 HTTP 状态码都返回 200;
- 直接在地址栏按回车时,所有资源都是从缓存获得的。
下面将分别说明,尤其是你会注意到一些细节,比如,图像 tip-sprite.gif,还有有些图像资源,无论你采用哪种方式刷新,都不会向服务器请求等等,这些细节对在开发 Web 应用程序中,提高其性能很有帮助。
初次访问
先看下“初次访问”页面的情况,如下图所示:
图3 初次访问
说明:
- 红色垂直线表示 Page Load 阶段,主要获得了 Ext.Net 嵌入资源的脚本和 CSS 文件,以及在程序集中自定义的一个脚本 myTreePanel.js。
- 绿色垂直线表示 Render Start 阶段,在Page Load 基础上,就可以呈现页面了。
- 灰色垂直线表示 HTTP Load 阶段,在Render Start 阶段,页面呈现时,以“渐进增强”的方式,向服务器请求资源,在该演示中主要是图像。例如,请求了按钮图片,不能拖拽的图片,还有树形结构的文件夹和箭头图标等。
参考博文 "以 Ext.Net 为例了解网页测试工具 HttpWatch"。
按 F5
图4 初次访问后按 F5
说明:
- 重新请求了 Default.aspx 页面,但页面中的其他资源没有,只是返回了 HTTP 状态码 304,告诉客户端请求的资源的没有被修改。而且客户端接收的字节数,与初次访问相比,小得可怜,才 226 bytes。
- 图像 tip-sprite.gif 是从缓存获得的。
按 Ctl-R
图5 初次访问后按 Ctl-R
说明:
- 与 F5 效果和执行的操作的一样。
- 重新请求 Default.aspx 页面。页面中的其他资源没有,只是返回了 HTTP 状态码 304,而且客户端接收的字节数也是 226 bytes。图像 tip-sprite.gif 也是从缓存获得。
如果你看下 Ext.Net.ResourceHandler 类的 ProcessRequest 方法,代码如下:
public override void ProcessRequest(HttpContext context)
{
this.context = context;
string file = this.context.Request.RawUrl;
bool isInitScript = file.Contains("extnet/extnet-init-js/ext.axd?");
if (!ResourceHandler.IsSourceModified(context.Request) && !isInitScript)
{
context.Response.SuppressContent = true;
context.Response.StatusCode = 304;
context.Response.StatusDescription = "Not Modified";
context.Response.AddHeader("Content-Length", "0");
return;
}
……
}
}
当客户端再次请求资源时,Ext.Net 会判断自己的相关嵌入资源(即 !ResourceHandler.IsSourceModified(context.Request) && !isInitScript,不是用户自定义脚本且没有被修改)是否被修改,如果没有被修改,就直接返回给客户端 304。下面代码是 Ext.Net 如何判断自己的资源是否被修改:
private static bool IsSourceModified(HttpRequest request)
{
bool dateModified = false;
string requestIfModifiedSinceHeader = request.Headers["If-Modified-Since"] ?? string.Empty;
DateTime requestIfModifiedSince;
DateTime.TryParse(requestIfModifiedSinceHeader, out requestIfModifiedSince);
DateTime responseLastModified = new DateTime(ResourceHandler.GetAssemblyTime(typeof(ResourceHandler).Assembly)).ToUniversalTime();
if (requestIfModifiedSince != DateTime.MinValue && responseLastModified != DateTime.MinValue)
{
requestIfModifiedSince = requestIfModifiedSince.ToUniversalTime();
if (responseLastModified > requestIfModifiedSince)
{
TimeSpan diff = responseLastModified - requestIfModifiedSince;
if (diff > TimeSpan.FromSeconds(1))
{
dateModified = true;
}
}
}
else
{
dateModified = true;
}
return dateModified;
}
从代码中看出,requestIfModifiedSince 是客户端中资源的最后修改时间,responseLastModified 是服务器端中程序集嵌入资源的最后修改时间。当 responseLastModified > requestIfModifiedSince,且 responseLastModified – requestIfModifiedSince > TimeSpan.FromSeconds(1) 时,说明服务器端的资源已经被修改,需要重新把该资源发送给客户端。
按 Ctl-F5
图6 初次访问后按 Ctl-F5
说明:
- 除重新请求了 Default.aspx 页面外,还重新请求了页面中的其他资源,就像客户端初次访问一样。
- 但是,我们知道,本文四种刷新界面的方式是连续进行的。因此,当执行 Ctl-F5 时,浏览器已经有缓存了该页面的相关资源,但是 Ctl-F5 没有使用,而是直接向服务器重新请求。
- 可是图像 tip-sprite.gif 仍然是从缓存获得的。
直接在地址栏按回车
图7 初次访问后在地址栏按回车
说明:
无论是 Default.aspx 页面,还页面中的其他资源,都是从缓存中获得的。
备注
- 这四种刷新方式:F5、Ctl-R、Ctl-F5 和直接在地址栏按回车。当页面被初次访问后,F5 和 Ctl-R 的操作和效果相同,虽然也发送了请求,但是服务器通过对请求脚本和 CSS 文件的 HTTP 头的日期比较,告诉客户端资源没有任何改变,可以直接其缓存中获得;Ctl-F5 不访问缓存,重新请求页面,及其中的资源,包括脚本和 CSS,就像初次访问页面一样;直接在地址栏按回车,不向服务器发送请求,直接从缓存中获得。
- 但是,既然 Ctl-F5 不访问本地缓存,但是为什么资源 tip-sprite.gif 图像还是从缓存中获得的?F5 和 Ctl-R 也是如此。
- 不仅如此,与初次访问页面相比,F5、Ctl-R、Ctl-F5 和直接在地址栏按回车发出 HTTP 请求的次数要少一半。这些重新请求的资源主要是 CSS 文件和脚本,而好几个图像都没再请求了。
- 没再请求的资源应该得益与 HTTP Expire 头。试想,有这样一个资源,它几乎不会被修改。因此,如果设置它“永不过期”的话,那么在初次访问后,这样的资源就不会 HTTP 请求。
参考资料
Internet Explorer Keyboard Shortcuts
http://www.updatexp.com/internet-explorer-keyboard-shortcuts.html
http://windows.microsoft.com/en-US/windows7/Internet-Explorer-keyboard-shortcuts
Wikipedia:Bypass your cache http://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache#cite_note-0
Using Ctrl+F5 in IE 7 http://blog.httpwatch.com/2007/10/19/using-ctrlf5-in-ie-7/
用 Ext.Net 程序演示 IE 的 F5/Ctl
TAG:Ext Net ASP NET Web开发 HttpWatch