Http 缓存机制作为 web 性能优化的重要手段,有如下作用:
- 减少网络带宽消耗:无论对于网站运营者或者用户,带宽都代表着金钱,过多的带宽消耗,只会便宜了网络运营商。当Web缓存副本被使用时,只会产生极小的网络流量,可以有效的降低运营成本。
- 降低服务器压力:给网络资源设定有效期之后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力。同时,搜索引擎的爬虫也能根据过期机制降低爬取的频率,也能有效降低服务器的压力。
- 减少网络延迟,加快页面打开速度:带宽对于个人网站运营者来说是十分重要,而对于大型的互联网公司来说,可能有时因为钱多而真的不在乎。那Web缓存还有作用吗?答案是肯定的,对于最终用户,缓存的使用能够明显加快页面打开速度,达到更好的体验。
以下是对HTTP中控制客户端缓存的几种方式以及优先级的梳理
强制缓存
浏览器在请求已经访问过的URL的时候, 会判断是否使用缓存, 判断是否使用缓存主要通过判断缓存是否在有效期内, 通过两个字段来判断:
- Expires, 有效期, 返回的是一个GMT时间,这是一个绝对时间, 但是使用的是客户端时间, 与服务器时间存在一定时间差
- Cache-Control => max-age, 最大有效时间,这是一个相对时间, 单位是s, 优先级比expires高, 为了解决expires时间差的问题而出现的
对比缓存
当缓存过期后, 浏览器不会直接去服务器上拿缓存, 而是判断缓存是否有更新, 能否继续使用, 判断的方法有两种:
- Last-Modified 和 If-Modified-Since: 服务器会响应一个Last-Modified字段, 表示最近一次修改缓存的时间, 当缓存过期后, 浏览器就会把这个时间放在If-Modified-Since去请求服务器, 判断缓存是否有更新
- Etag和If-None-Match: 服务器会响应一个Etag字段, 一个表示文件唯一的标识符, 一旦文件更新, Etag也会跟着更改, 当缓存过期后, 浏览器会把这个唯一标识符放在If-None-Match去请求服务器, 判断是否有更新, Etag的优先级比Last-Modified的更高
那么既生Last-Modified何生Etag?你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形