在看Spring中HttpServlet的Service方法时,对于GET请求,代码逻辑如下:

if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
} }

其中涉及的关键信息是修改时间,这就涉及到浏览器数据缓存问题。以下对个缓存机制进行简单总结,可用于请求的优化。(本文中的图都摘自其他文章

Last-Modified和If-Modified-Since

当浏览器GET请求的时候,如果有If-Modified-Since,则会与当前服务器上相关资源最后一次修改时间进行对比,如果相同则返回304(资源可访问,但没修改),否则加载最新数据,浏览器再缓存起来。这样减少网络数据传输和服务器压力。

ETags和If-None-Match

根据修改时间判断文件是否被修改,如果一个网页被频繁更新,但实际内容并没有更新,依然会对服务器造成压力。引入了ETags和If-None-Match,其不同于Last-Modified和If-Modified-Since取决于修改时间,可以依赖其他属性,如资源的MD5等。当资源被更新,但实际内容没有更新,则会比较修改时间和ETags,如果ETags没变,则不更新数据资源。但查阅源码戴发现,目前底层实现上实现的是弱Etags,其由文本长度和修改时间组成,资源被更新后,ETags依然会更新。在AbstractResource中,代码如下:

  @Override
public final String getETag() {
if (weakETag == null) {
synchronized (this) {
if (weakETag == null) {
long contentLength = getContentLength();
long lastModified = getLastModified();
if ((contentLength >= 0) || (lastModified >= 0)) {
weakETag = "W/\"" + contentLength + "-" +
lastModified + "\"";
}
}
}
}
return weakETag;
}

Expires

添加Expires头能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的Http请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止。例如:Expires:Thu,15 Apr  2010  20:00:00  GMT;  他告诉浏览器缓存有效性持续到2010年4月15日为止,在这个时间之内相同的请求使用缓存,这个时间之外使用http请求。Expires有一个非常大的缺陷,它使用一个固定的时间,要求服务器与客户端的时钟保持严格的同步,并且这一天到来后,服务器还得重新设定新的时间。

Cache-Control

HTTP1.1引入了Cathe-Control,它使用max-age指定组件被缓存多久(时间相对请求的时间),从请求开始在max-age时间内浏览器使用缓存,之外的使用请求,这样就可以消除Expires的限制。但有个缺点就是,用户不能第一时间拿到最新修改的文件。请求过程如下:

另外,gulp 给静态资源文件添加hash(md5)后缀防止缓存无效,能获取最新文件(这个需要进一步研究)

参考:

HTTP的请求头标签 If-Modified-Since

If-Modified-Since和If-None-Match

http://www.360doc.com/content/17/0721/17/41344223_673116604.shtml

前端性能优化 —— 添加Expires头

最新文章

  1. Android中的AlertDialog使用示例二(普通选项对话框)
  2. suid sgid sbit chattr lsattr
  3. Centos搭建Python+Nginx+Tornado+Mysql环境[转载]
  4. javaweb页面上展示动态图片
  5. 设置SecureCRT会话的缓冲区大小
  6. MFC中使用Duilib--1
  7. C#Winfrom中,窗体加载时会自动执行一次控件的textchange事件,怎么让它不执行?
  8. 解决Redis Cluster模式下的排序问题
  9. css布局学习笔记之position属性
  10. linux LVS DR模式配置
  11. Meterpreter
  12. VBS 选择文件夹框
  13. Android Foreground Service (前台服务)
  14. jQuery手机端点击弹出分享按钮代码
  15. PHP+Mysql学习笔记
  16. Docker machine(Docker 虚拟机)
  17. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理(转)
  18. Running CMD.EXE as Local System(转)
  19. HDU - 3068 最长回文(马拉车Manacher)题解
  20. Java学习笔记(2)----散列集/线性表/队列/集合/图(Set,List,Queue,Collection,Map)

热门文章

  1. TCP 123=网络时间协议(NTP),Net Controller
  2. express 默认模板引擎
  3. sql server作业管理查看/进程管理查看命令
  4. OC 手势可能出现的问题
  5. [py]django强悍的数据库接口(QuerySet API)-增删改查
  6. 使用免费的Let&#39;s Encrypt通配符证书 升级我们的网站
  7. python处理图片验证码
  8. testng入门教程8 TestNG异常测试
  9. android studio 错误: 编码GBK的不可映射字符
  10. 【调优】Nginx性能调优