web缓存总结

什么是Web缓存

Web缓存是指一个Web资源(如html页面,图片,js,数据等)存在于Web服务器和客户端(浏览器)之间的副本。缓存会根据进来的请求保存输出内容的副本;当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页。

Web缓存的作用

  1. 减少网络带宽消耗
  2. 降低服务器压力
  3. 减少网络延迟,加快页面打开速度

Web缓存的类型

  1. 数据库数据缓存,如redis,memcached等
  2. 服务器端缓存,如代理服务器缓存,CDN缓存
  3. 浏览器端缓存
  4. Web应用层缓存

浏览器缓存的控制

最有效的一个方法是使用缓存有关的HTTP消息报头
在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头有:
alt text

用户操作行为与缓存

用户在使用浏览器的时候,会有各种操作,比如输入地址后回车,按F5刷新等,这些行为会对缓存有什么影响呢?
alt text

当用户使用Ctrl+F5进行强制刷新的时候,只是所有的缓存机制都将失效,重新从服务器拉去资源。

哪些请求不能被缓存?

  1. HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
  2. 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
  3. 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存)
  4. POST请求无法被缓存(GET可以)
  5. HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存

如何构建可缓存站点

  1. 对于不经常修改的静态资源,比如Css,js,图片等,可以设置一个较长的过期的时间,或者至少加上Last-Modified/Etag,而对于html页面这种入口文件,不建议设置缓存。这样既能保证在静态资源不变了情况下,可以不重发请求或直接通过304避免重复下载,又能保证在资源有更新的,只要通过给资源增加时间戳或者更换路径,就能让用户访问最新的资源
  2. 过多的使用Cookie会大大增加HTTP请求的负担,每次GET或POST请求,都会把Cookie都带上,增加网络传输流量,导致增长交互时间;同时Cache是很难被缓存的,应该尽量少使用,或者这在动态页面上使用。
  3. 通过HTTPS请求的资源,默认是不会被缓存的,必须通过特殊的配置,才能让资源得到缓存。建议只对涉及敏感信息的请求使用HTTPS传输,其他类似Css,Js,图片这些静态资源,尽量避免使用。
  4. 虽然POST的请求方式比Get更安全,可以避免类似密码这种敏感信息在网络传输,被代理或其他人截获,但是Get请求方式更快,效率更高,而且能被缓存,建议对于那些不涉及敏感信息提交的请求尽量使用Get方式请求

如何给站点增加缓存机制

HTTP请求/响应头中缓存报头对有效利用站点缓存,作为一个Web前端开发者,我要做什么呢?答案是:啥都不用做。不过要去推动Web运营人员、Web后端开发人员分别给服务器和动态脚本CGI增加合适的缓存报头。可以从以下方面入手:

  1. 服务器配置:Apache相关配置参考
  2. 编写可缓存的动态脚本:服务器配置的方法比较简单通用,但是如果遇到没有权限修改服务器配置或者需要添加更细致的Expires/Cache-Control/Etag等信息时,不妨可以试试从代码层面去添加这些信息。不同语言写法实现略有不同,但思路都是一致的。可以在单独开辟一个独立模块,调用语言库提供的添加报头的接口,根据需要设置报头信息。当某个请求的动态脚本需要被缓存时,可以采用类似include,require等模块引用方式调用公共模块,实现缓存机制。

缓存Ajax请求

Ajax调用就像任何其他的HTTP请求一样可以用来构建一个网页。然而,由于其动态的性质人们常常忽略了可以缓存它们而从中受益。
Ajax缓存和HTTP缓存效果相同,当然,如果您使用Ajax的POST方法,这并不适用,因为POST请求不会被缓存。如果您的Ajax请求有安全性要求,你应该总是使用POST方法,例如:银行帐户的资金转账。

通过Javascript实现内存缓存

跟缓存Ajax请求的结果类似,程序运行过程中的其他数据,其实也可以采用类似的方式在顶级容器的Javascript上下文中缓存(其实就是设置一个全局变量,将数据写入全局变量中)。

实际测试浏览器缓存

以在chrome中打开腾讯为例,
首次打开无缓存:
alt text
第二次打开有缓存:
alt text
alt text

memoryCache和diskCache

MemoryCache顾名思义,就是将资源缓存到内存中,等待下次访问时不需要重新下载资源,而直接从内存中获取。Webkit早已支持memoryCache。
diskCache就是将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而直接从磁盘中获取,它的直接操作对象为CurlCacheManager。它与memoryCache最大的区别在于,当退出进程时,内存中的数据会被清空,而磁盘的数据不会,所以,当下次再进入该进程时,该进程仍可以从diskCache中获得数据,而memoryCache则不行。

参考文档

  1. Web缓存的作用与类型http://www.alloyteam.com/2012/03/web-cache-1-web-cache-overview/
  2. Ajax 缓存: 两个重要的事实http://www.cnblogs.com/yslow/archive/2009/08/28/1555777.html
请我吃辣条~~