浏览器缓存策略详解

关于cache的分类

  • 按缓存位置分类 (memory cache, disk cache, Service Worker 等)

  • 按失效策略分类 ( Cache-Control, ETag 等)

发网络请求时会按照这个原则来:

  1. Service Worker

  2. Memory Cache

  3. Disk Cache

  4. 网络请求

每个域名 cookie是在浏览器关闭的情况下就失效

浏览器的tab关闭后该浏览器memory cache便告失效 1.preloader 将请求的资源放入memory cache中,供之后的解析执行操作使用

2.preload 。这些显式指定的预加载资源

“请求 js/css - 解析执行 - 请求下一个 js/css - 解析执行下一个 js/css”

service worker 能够操作的缓存是有别于浏览器内部的memory cache或者disk cache。缓存是永久性的,即便关闭了tab。有两种情况会导致这个缓存中的资源被清除:手动调用 API cache.delete(resource) 或者容量超过限制,被浏览器全部清空。

请求网络之后会根据情况决定是否缓存

  1. 根据 Service Worker 中的 handler 决定是否存入 Cache Storage (额外的缓存位置)。

  2. 根据 HTTP 头部的相关字段( Cache-control, Pragma 等)决定是否存入 disk cache

  3. memory cache 保存一份资源 的引用,以备下次使用。

memory cache是浏览器控制的,不受开发者控制,也不受http协议头的约束

  1. 所以我们平时最为熟悉的其实是 disk cache,也叫 HTTP cache (因为不像 memory cache,它遵守 HTTP 协议头中的字段)。

  2. 平时所说的强制缓存,对比缓存,以及 Cache-Control 等,也都归于此类。

强缓存 强制缓存的含义是,当客户端请求后,会先访问缓存数据库看缓存是否存在。如果存在则直接返回;不存在则请求真的服务器,响应后再写入缓存数据库。

强制缓存直接减少请求数,是提升最大的缓存策略。 它的优化覆盖了文章开头提到过的请求数据的全部三个步骤。如果考虑使用缓存来优化网页性能的话,强制缓存应该是首先被考虑的。

可以造成强制缓存的字段是 Cache-control 和 Expires

强缓存

分析对比cache-control 和 expires

关于 Cache-Control: max-age=秒 和 Expires Expires = 时间,HTTP 1.0 版本,缓存的载止时间,允许客户端在这个时间之前不去检查(发请求) max-age = 秒,HTTP 1.1版本,资源在本地缓存多少秒。

no-cache no-cache(无缓存)不意味着根本没有缓存,它只是告诉浏览器在使用缓存之前先验证服务器上的资源。

Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

考虑到 expires 的局限性,HTTP1.1 新增了 Cache-Control 字段来完成 expires 的任务。 expires 能做的事情,Cache-Control 都能做;expires 完成不了的事情,Cache-Control 也能做。因此,Cache-Control 可以视作是 expires 的完全替代方案。在当下的前端实践里,我们继续使用 expires 的唯一目的就是向下兼容。

协商缓存

ETag和last-modified

  • 根据上次响应中的ETag_value,自动往request header 中添加if-none-match 字段, 服务器收到请求后,拿if-none-match字段的值与资源的etag值进行比较,若相同,则命中协商缓存,返回 304 响应

  • 根据上次响应中的last-modified—value,自动往request header 中添加if-modified-since字段。服务器收到请求后,拿if-modified-since字段的值与资源的last-modified值进行比较,若相同,则命中协商缓存,则返回 304 响应

304 Not Modified:客户端有缓冲的文件并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓存的文档还可以继续使用。

如果客户端在请求一个文件的时候,发现自己缓存的文件有 Last Modified ,那么在请求中会包含 If Modified Since ,这个时间就是缓存文件的 Last Modified 。因此,如果请求中包含 If Modified Since,就说明已经有缓存在客户端。只要判断这个时间和当前请求的文件的修改时间就可以确定是返回 304 还是 200 。对于静态文件,例如:CSS、图片,服务器会自动完成 Last Modified 和 If Modified Since 的比较,完成缓存或者更新。但是对于动态页面,就是动态产生的页面,往往没有包含 Last Modified 信息,这样浏览器、网关等都不会做缓存,也就是在每次请求的时候都完成一个 200 的请求。

一般的大的站点的图片服务器都有实现HTTP 304 缓存功能。 这个 304 状态一般主要在用户刷新页面(F5键)的时候触发,当用户在刷新页面的时候,因为原来的页面里的很多图片已经缓存过,客户端的浏览器已经记录了图片的最后更新时间(Last Modified),所以在用户刷新页面的时候,会向服务器提交一个字段:If-Modified-Since: Wed, 08 Sep 2010 21:35:06 GMT 这个时候,服务器端的程序先取得这个字段的值,然后与服务器上的图片最后修改时间对比,如果相同,就直接返回 304 Not Modified ,然后停止。这样就不用把图片重新传输到客户端,达到节省带宽的目的。

两种刷新方式

f5的刷新

可以看到f5可以被称为soft refresh 其只是reload page而已。 即与回车地址相同,正常规则下的缓存还是会涉及到。

强制 f5 强制

刷新此时的刷新可以称为hard refresh, 请求会加上一个Cache-Control:no-cache的标识来表明突破cache-control的限制, 需要服务端重新判断有效性,即不走强缓存。 另外请求header中去掉If-None-Match,这样就不能使用协商缓存。拉到新的资源

get 和 post 的区别

  • get 请求 会被缓存 post 请求不会

    首先要了解什么是缓存。

HTTP缓存的基本目的就是使应用执行的更快,更易扩展,但是HTTP缓存通常只适用于idempotent request(可以理解为查询请求,也就是不更新服务端数据的请求),这也就导致了在HTTP的世界里,一般都是对Get请求做缓存,Post请求很少有缓存。

get多用来直接获取数据,不修改数据,主要目的就是DB的search语句的感觉。用缓存(有个代理服务器的概念)的目的就是查db的速度变快。

post则是发送数据到服务器端去存储。类似db里的update delete和insert语句的感觉。更新db的意思。数据必须放在数据库,所以一般都得去访问服务器端。

  • 安全问题。

get到服务器过程中数据都是在url中,也就是说要传送的数据是可以在链接里面看到,就有安全问题。因为是一个url,所以就跟百度网址一样,好理解啦吧。

post就不是在url里面所有还是比较安全的

最后更新于