缓存篇--浏览器缓存

为什么使用浏览器缓存

互联网应用系统,在高并发的情况下,都会使用缓存,例如:浏览器缓存,CDN缓存,Nginx反向代理缓存,应用多级缓存,以及数据库缓存等等,如下

http请求可缓存节点

缓存的目的是为了让数据离用户更近,使用户能够以最快的速度获取到数据同时降低对后端系统压力,今天我们将介绍,离用户最近的缓存,浏览器缓存的使用,浏览器缓存依赖于,Http协议规范,可在响应头(Reponse Header)声明缓存策略

缓存请求

浏览器缓存请求到本地,需要解决一个问题,即缓存如何更新,因为内容是由web服务器更新,却存在于本地浏览器,所以他们之间必须建立起一种沟通机制,即HTTP“缓存协商”
浏览器如何协商缓存?首先服务端响应头(Reponse Header)会返回Last-Modified,如下:

Last-Modified:Sun, 07 May 2017 07:34:12 GMT

浏览器下次请求,请求头(Request Header)将带上

If-Modified-Since:Sun, 07 May 2017 07:34:12 GMT

这样浏览器根据返回的时间,确认请求内容是否更新,如果没有更新则返回状态码HTTP 304,告诉浏览器Not Modified可直接使用本地缓存,下面以java代码来实现如下

@RequestMapping("/cache")
public ResponseEntity cache(@RequestHeader(value = "If-Modified-Since", required = false) Date modifiedSence, HttpServletResponse response) {
     //缓存1天
     long nowTime = new Date().getTime();
     if(modifiedSence!=null) {
         long expireTime = modifiedSence.getTime() + 24 * 3600 * 1000;
         //未过期
         if (nowTime<expireTime) {
             return new ResponseEntity("cached", HttpStatus.NOT_MODIFIED);
         }
     }
     response.setDateHeader("Last-Modified", nowTime);
     return new ResponseEntity("not cache", HttpStatus.OK);
}

还有一种协商策略基于请求头的ETag,如:ETag:W/"590ecdf4-1a6",服务器端比对资源的Etag,确定资源是否变更

消灭请求

跟据上节所讲,浏览器会发送请求到服务器检查缓存是否有更新,在大多数场景下面,这样依然能够提高服务器的性能以及吞吐率,能否彻底消灭不必要的请求呢?答案是可以的,只需要标记Expires过期时间,下面将以nginx(1.10+版本),chrome(测试浏览器)作为示例

# 针对url http://localhost:8080/hello/ 下面所有文件做缓存处理,缓存两天
location ^~ /hello/ {
     expires 20d;
} 

访问则浏览器会响应头(Reponse Header),会携带如下信息

Cache-Control:max-age=1728000
ETag:W/"590ecfcb-fb"
Expires:Sat, 27 May 2017 07:43:20 GMT # 日期可能不同
Last-Modified:Sun, 07 May 2017 07:42:03 GMT #日期可能不同

Expires说明,缓存起作用了,但是Expires会存在一个问题,即来自于web服务器的时间可能和本地时间不一致,会影响到本地缓存的有效性检查

Cache-Control可弥补Expires的不足,max-age直接指定了缓存过期的相对时间,这个时间是相对于浏览器本地的时间

再次请求点击浏览器刷新按钮,监视到请求返回到状态码是

Status Code:304 Not Modified

缓存没有起作用,还是发起了请求,这里表示很奇怪,网上查找资料,发现其实浏览器针对刷新请求响应行为如下

用户行为与浏览器缓存行为

知道了浏览器的属性,我们可以模拟常用场景,从一个页面B跳转到我们需要测试页面A的,发现成功了,浏览器没有发起请求,如下

Status Code:200 OK (from disk cache)

如何使用浏览器缓存

一般情况下针对不同的场景,采取不同的缓存策略
1、站点的静态资源请求最适合使用浏览器缓存,这样能减轻服务器的压力,降低出口带宽压力
2、动态请求一般依据策略区分,写请求自然不会缓存,针对读请求,则看场景是否对一致性要求比较高,例如:页面上的新闻列表,可缓存下来,每隔n分钟刷新一次

参考文档

[1] 构建高性能web站点 郭欣著
[2] Spring官方文档

示例

[1] http-cache

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • API定义规范 本规范设计基于如下使用场景: 请求频率不是非常高:如果产品的使用周期内请求频率非常高,建议使用双通...
    有涯逐无涯阅读 7,761评论 0 6
  • 浏览器缓存,也就是客户端缓存,既是网页性能优化里面静态资源相关优化的一大利器,也是无数web开发人员在工作过程不可...
    Www刘阅读 3,593评论 0 1
  • 浅谈浏览器Http的缓存机制 ✦ ✦ ✦ ✦ ✦ ✦ ✦ ✦ 针对浏览器的http缓存的分析也算是老生常谈了,每隔...
    meng_philip123阅读 4,683评论 0 10
  • 本文内容大多参考《图解HTTP》一书 一. 认识代理服务器 所以讲缓存为什么要先扯代理服务器?别急,让我们看一下一...
    流光号船长阅读 6,075评论 0 10
  • 转载:浏览器缓存知识小结及应用 阅读目录 1. 浏览器缓存基本认识 2. 强缓存的原理 3. 强缓存的管理 4. ...
    meng_philip123阅读 4,731评论 4 18