浏览器缓存整理

对浏览器缓存这一块一直是乱哄哄的状态,今天终于有时间整理一下,写下这篇笔记,以供往后查阅。git

缓存概述

良好的缓存策略能够下降资源的重复加载提升网页的总体加载速度
一般浏览器缓存策略分为两种:强缓存和协商缓存github

基本流程

  1. 浏览器在加载资源时,根据请求头的expires和cache-control判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。
  2. 若是没有命中强缓存,浏览器必定会发送一个请求到服务器,经过last-modified和etag验证资源是否命中协商缓存,若是命中,服务器会将这个请求返回,可是不会返回这个资源的数据,依然是从缓存中读取资源
  3. 若是前面二者都没有命中,直接从服务器加载资源

相同点

若是命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;web

不一样点

强缓存不发请求到服务器,协商缓存会发请求到服务器。segmentfault

强缓存

强缓存经过ExpiresCache-Control两种响应头实现浏览器

Expires

Expires是http1.0提出的一个表示资源过时时间的header,它描述的是一个绝对时间,由服务器返回。
Expires 受限于本地时间,若是修改了本地时间,可能会形成缓存失效缓存

Expires: Sat, 29 Sep 2018 14:20:00 GMT

Cache-Control

Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires ,表示的是相对时间服务器

Cache-Control: max-age=315360000

Cache-Control在request和response中均可以使用负载均衡

  1. 在请求中使用Cache-Control 时,它可选的值有:

Cache-Control在请求头中的取值

  1. 在响应中使用Cache-Control 时,它可选的值有:

Cache-Control在响应头中的取值

强缓存流程图

强缓存流程图

协商缓存

当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,若是协商缓存命中,请求响应返回的http状态为304而且会显示一个Not Modified的字符串分布式

协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对Header来管理的google

Last-Modified,If-Modified-Since

Last-Modified 表示请求来的文件的最后修改日期,浏览器会在request header加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。

ETag、If-None-Match

Etag就像一个指纹,资源变化都会致使ETag变化,跟最后修改时间没有关系,ETag能够保证每个资源是惟一的

If-None-Match的header会将上次返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变更就会发送新的资源回来

ETag的优先级比Last-Modified更高

大体流程

  1. 客户端请求一个页面(A)。
  2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
  3. 客户端展示该页面,并将页面连同Last-Modified/ETag一块儿缓存。
  4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一块儿传递给服务器。
  5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求以后还未被修改,直接返回响应304和一个空的响应体。

感受两个功能重复了?

ETag对Last-Modified的补充

首先Last-Modified在http/1.0中被提出,而在http/1.1中提出的ETag则是为了解决Last-Modified没法解决的一些问题

  1. 一些文件也许会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET;
  2. 某些文件修改很是频繁,好比在秒如下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改没法判断(或者说UNIX记录MTIME只能精确到秒);
  3. 某些服务器不能精确的获得文件的最后修改时间。

Last-Modified对ETag的补充

一些图片等静态文件的修改,若是每次扫描内容生成 ETag 来比较,显然要比直接比较修改时间慢不少

小结

因此说二者并非互斥,而是相辅相成的关系,既能够单独使用,又能够同时使用。

同时传入服务器时,服务器能够根据本身的缓存机制的须要,选择ETag或者是Last-Modified来作缓存判断的依据,甚至能够两个同时参考。

如何使用

协商缓存须要配合强缓存使用,若是不启用强缓存的话,协商缓存根本没有意义

大部分web服务器都默认开启协商缓存,并且是同时启用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】

Apache对于静态内容默认会返回Last-modified和ETag.

Nginx只会返回Last-modified(可配置etag on开启).

可是下面的场景须要注意:

  • 分布式系统里多台机器间文件的Last-Modified必须保持一致,以避免负载均衡到不一样机器致使比对失败;
  • 分布式系统尽可能关闭掉ETag(每台机器生成的ETag都会不同)

总体流程图

浏览器缓存整理

参考

https://github.com/amandakela...
https://blog.csdn.net/u012375...
https://segmentfault.com/q/10...
baidu and google

原文在这里

相关文章
相关标签/搜索