浏览器缓存系列之一:基础知识必备

Posted 指尖下的精灵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器缓存系列之一:基础知识必备相关的知识,希望对你有一定的参考价值。

之前,由于公司需求搭建了公司的前端框架,后来在做性能优化时,通过插件检测说是使用浏览器缓存能够大大提高响应速度。本来以为还是比较好做的,但是,按着自己的想法做了很多的尝试,都不能成功。后来,转变思维模式,不仅仅局限在前端,哎,总之,绕了好大一圈才做好,花费了不少的时间。 下面小编将从零撸一遍关于浏览器缓存方面的知识:

一、什么是浏览器缓存?

在Web性能优化上,我们总是追求网页能快速打开相应,这时就是浏览器缓存上场的时间了。

概念:当浏览器向服务器发起资源请求后,相应后会加载各种资源:html页面、图片、JS文件、CSS文件,对于一些不经常变的内容,浏览器会将它们缓存下来,等下次再访问的时候,就直接从客户端加载这些资源了。 这些被浏览器保存下来的资源成为缓存。(注意:和cookie和localStorage是不同的概念)

二、缓存的分类

强缓存:http状态码为200 强缓存就是判断缓存是否在有效期内,如果在,则直接从客户端获取资源,不会发送请求向服务端。即使请求的资源已经更新。 Expires是HTTP 1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT,包含了Expires头标签的文件,就说明浏览器对于该文件缓存具有非常大的控制权。      Expires是较老的强缓存管理header,由于它是服务器返回的一个绝对时间,在服务器时间与客户端时间相差较大时,缓存管理容易出现问题,比如:随意修改下客户端时间,就能影响缓存命中的结果。所以在HTTP 1.1的时候,提出了一个新的header,就是Cache-Control,这是一个相对时间,在配置缓存的时候,以秒为单位,用数值表示     Cache-Control描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,所以相比较Expires,Cache-Control的缓存管理更有效,安全一些。     这两个header可以只启用一个,也可以同时启用,当response header中,Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires。协商缓存:Last-Modified&Etag(是否更新): 当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的http状态为304并且会显示一个Not Modified的字符串

三、关于浏览器缓存

1、200 from memory cache 不访问服务器,直接读缓存,从内存中读取缓存。此时的数据时缓存到内存中的,当kill进程后,也就是浏览器关闭以后,数据将不存在。但是这种方式只能缓存派生资源

2、200 from disk cache 不访问服务器,直接读缓存,从磁盘中读取缓存,当kill进程时,数据还是存在。这种方式也只能缓存派生资源

3、304 Not Modified 访问服务器,发现数据没有更新,服务器返回此状态码。然后从缓存中读取数据。

3.1、浏览器缓存的三级缓存原理

1、先去内存看,如果有,直接加载 2、如果内存没有,择取硬盘获取,如果有直接加载 3、如果硬盘也没有,那么就进行网络请求 4、加载到的资源缓存到硬盘和内存 一般浏览图片,如下流程:

访问-> 200 -> 退出浏览器 再进来-> 200(from disk cache) -> 刷新 -> 200(from memory cache)

4、application cache和上面缓存有点区别,是离线缓存,就是资源可以从硬盘上读取而不用联网,即使断网,用户也可以浏览。

四、HTTP中的Cache-Control和Expires

做浏览器缓存离不开要使用Cache-Control和Expires这两个属性。 Web页面设计中,建少HTTP请求可以提高页面响应速度。浏览器在第一次访问页面时下载的资源会缓存起来,第二次访问时会判断在缓存中是否已有该资源并且有没有更新过,如果已有该资源且没有更新过,则去缓存去取,这样减少了下载资源的时间。原理:通过HTTP Rquest Header中的 if-modified-since 和Response Headers中的last-modified来实现(还有一对组合If-None-Match和Etag,类似,但有细微差别,不属于本文重点讨论范围,如有兴趣可参考链接Google Developers 优化性能指导),HTTP请求把if-modified-sincede 时间传给服务端,服务端把last-modified时间与之对比,如果相同,则意味着文件没有改动,则返回304,浏览器则从缓存中获取资源,无需下载。虽然这种方法减少了已缓存资源的下载时间,但是仍然发起了一次http请求。仍然还有更激进的做法来节省也页面加载的时间,就是免去该资源的http请求。即接下来的主角,HTTP的Expires和Cache-Control。

Cache-Control 的参数包括:

  • max-age=[单位:秒 seconds] — 设置缓存最大的有效时间. 类似于 Expires, 但是这个参数定义的是时间大小(比如:60)而不是确定的时间点.单位是[秒 seconds].

  • s-maxage=[单位:秒 seconds] — 类似于 max-age, 但是它只用于公享缓存 (e.g., proxy) .

  • public — 响应会被缓存,并且在多用户间共享。正常情况, 如果要求 HTTP 认证,响应会自动设置为 private.

  • private — 响应只能够作为私有的缓存(e.g., 在一个浏览器中),不能再用户间共享。

  • no-cache — 响应不会被缓存,而是实时向服务器端请求资源。这一点很有用,这对保证HTTP 认证能够严格地禁止缓存以保证安全性很有用(这是指页面与public结合使用的情况下).既没有牺牲缓存的效率,又能保证安全。

  • no-store — 在任何条件下,响应都不会被缓存,并且不会被写入到客户端的磁盘里,这也是基于安全考虑的某些敏感的响应才会使用这个。

  • must-revalidate — 响应在特定条件下会被重用,以满足接下来的请求,但是它必须到服务器端去验证它是不是仍然是最新的。

  • proxy-revalidate — 类似于 must-revalidate,但不适用于代理缓存.

For example:

1、Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器。

2、 Cache-Control:max-age=3600,must-revalidate

如果Cache-Control 和 Expires 同时设置, Cache-Control 优先.如果你打算使用 Cache-Control ,别忘记好好看看关于 HTTP 1.1协议的文档

4.2、Expires

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

Cathe-Control:max-age=315360000

Expires有一个非常大的缺陷,它使用一个固定的时间,要求服务器与客户端的时钟保持严格的同步,并且这一天到来后,服务器还得重新设定新的时间。

HTTP1.1引入了Cathe-Control,它使用max-age指定组件被缓存多久,从请求开始在max-age时间内浏览器使用缓存,之外的使用请求,这样就可以消除Expires的限制,

如果对浏览器兼容性要求很高的话,可以两个都使用。

接下来用流程图详细的说明: 浏览器初次访问服务器---------------服务器返回200状态

浏览器再次请求服务器时,浏览器会先判断max-age,如果到期则直接请求服务器,否则直接从缓存中取,

服务器收到请求后,判断文件是否被修改过,若是则直接返回200,否则返回304,浏览器将从缓存中获取文件。

浏览器缓存系列之一:基础知识必备

若同步刷新页面,则浏览器并不会先判断max-age,而是直接发送请求,服务器接收到请求后,判断文件是否有变化,若有则返回200,若没有则返回304。

最后送一张浏览器缓存判断流程图:

如果该篇文章对您有帮助,请动一动您的小手指关注一波:


以上是关于浏览器缓存系列之一:基础知识必备的主要内容,如果未能解决你的问题,请参考以下文章

一文带你了解前端性能优化之HTTP缓存系列

缓存系列之一:buffercache与浏览器缓存

16个必备的JavaScript代码片段

「必备技能」Elasticsearch索引全生命周期管理(附代码)

玩转接口测试 & 性能测试 之 必备基础知识:Web协议

Spring Boot缓存应用实践