共计 2604 个字符,预计需要花费 7 分钟才能阅读完成。
一、Expires
Expires 是 web 服务器响应头字段,值是一个工夫类型,通知浏览器在过期工夫前能够间接从浏览器缓存中取数据,而无需再次申请。
Expires 是 http 1.0 的东东,在 http1.1 + 的场景下,其作用根本能够疏忽, 作用优先级最低
二、Cache-control
Cache-Control 与 Expires 作用相当。只不过 Cache-control 更多灵便,且优先级高于 Expires
Cache-Control 能够设置的值有很多,上面列出最罕用的几个:
no-cache: 所有内容都不会被缓存
no-store: 所有内容都不会被缓存到缓存或者 internet 临时文件中
max-age=xxx: 缓存的内容将在 xxx 秒后生效(这个选项只在 HTTP 1.1 可用, 并如果和 Last-Modified 一起应用时, 优先级较高)
三、Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since 要配合 Cache-Control 应用。
Last-Modified:标示这个响应资源的最初批改工夫。web 服务器在响应申请时,通知浏览器资源的最初批改工夫。
If-Modified-Since:当资源过期时(应用 Cache-Control 标识的 max-age),则再次向 web 服务器申请时带上头 If-Modified-Since(= Last-Modified 的值)。web 服务器收到申请后将 If-Modified-Since 与被申请资源的最初批改工夫进行比对,决定返回 304 或者 200(协商缓存)
四、Etag/If-None-Match
Etag/If-None-Match 也要配合 Cache-Control 应用。
Etag:web 服务器响应申请时,通知浏览器以后资源在服务器的惟一标识(比方 md5 hash)。
If-None-Match:当资源过期时(应用 Cache-Control 标识的 max-age), 则再次向 web 服务器申请时带上头 If-None-Match(= Etag 的值)。web 服务器收到申请后将 If-None-Match 则与被申请资源的相应校验串进行比对,决定返回 304 或者 200(协商缓存)。
五、既生 Last-Modified 何生 Etag?
你可能会感觉应用 Last-Modified 曾经足以让浏览器晓得本地的缓存正本是否足够新,为什么还须要 Etag(实体标识)呢?HTTP1.1 中 Etag 的呈现次要是为了解决几个 Last-Modified 比拟难解决的问题:
1: Last-Modified 标注的最初批改只能准确到秒级,如果某些文件在 1 秒钟以内,被批改屡次的话,它将不能精确标注文件的批改工夫
2: 如果某些文件会被定期生成,当有时内容并没有任何变动,但 Last-Modified 却扭转了,导致文件没法应用缓存
3: 有可能存在服务器没有精确获取文件批改工夫,或者与代理服务器工夫不统一等情景
Etag 是服务器主动生成或者由开发者生成的对应资源在服务器端的惟一标识符,可能更加精确的管制缓存。Last-Modified 与 ETag 是能够一起应用的,服务器会优先验证 ETag,统一的状况下,才会持续比对 Last-Modified,最初才决定是否返回 304。
六、from disk cache 和 from memory cache
Chrome 在高版本更新了缓存策略(具体版本遗记),原来的 from cache 变成了 from disk cache(磁盘缓存) 和 from memory cache(内存缓存) 两类,两者有什么区别呢?
先从官网文档来看下:
` Chrome employs two caches — an on-disk cache and a very fast in-memory cache. The lifetime of an in-memory cache is attached to the lifetime of a render process, which roughly corresponds to a tab. Requests that are answered from the in-memory cache are invisible to the web request API. If a request handler changes its behavior (for example, the behavior according to which requests are blocked), a simple page refresh might not respect this changed behavior. To make sure the behavior change goes through, call handlerBehaviorChanged() to flush the in-memory cache. But don’t do it often; flushing the cache is a very expensive operation. You don’t need to call handlerBehaviorChanged() after registering or unregistering an event listener.
`
谷歌翻译了一下,大略就是内存缓存是和渲染过程绑定的,大部分状况下于浏览器 Tab 对应(具体保留磁盘还是内存的逻辑不太分明,如果有晓得的请告知)。
因为内存缓存是间接从内存中读取的,所以速度更快,从图中能够看出工夫是 0ms。而磁盘缓存还须要从磁盘中读取,速度还和磁盘的 I / O 无关。
七、强缓存作用
强缓存作为性能优化中缓存方面最无效的伎俩,可能极大的晋升性能。因为强缓存不会向服务端发送申请,对服务端的压力也是大大减小。
对于不太常常变更的资源,能够设置一个超长工夫的缓存工夫,比方一年。浏览器在首次加载后,都会从缓存中读取。
然而因为不会向服务端发送申请,那么如果资源有更改的时候,怎么让浏览器晓得呢?当初罕用的解决办法是加一个?v=xxx 的版本后缀,在更新动态资源版本的时候,更新这个 v 的值,这样相当于向服务端发动一个新的申请,从而达到更新动态资源的目标。
八、浏览器缓存与前端构建
为了谋求最完满的缓存体验,通常 web server(如 nginx)会设置 Cache-Control: max-age 为一个很长的工夫,所以为了让文件在更新时能及时的在浏览器防止缓存,前端资源在构建时须要做 MD5 文件指纹解决。