首先缓存的优点是:缓解服务端压力;快。
强缓存和协商缓存
强缓存是从本地缓存数据表中去取资源,不向服务端发送请求;协商缓存意思是每次使用缓存前都要和服务端进行确认。
从Response Header的Cache-Control的值看缓存规则(HTTP/1.1):
max-age=xxx 过期时间(重要),过期了走协商缓存(expire是HTTP1.0的产物,采用绝对时间,已废弃)
no-cache:不进行强缓存(重要),走协商缓存
no-store 不强缓存,也不协商缓存,基本不用
public:浏览器和代理服务器都可以缓存
private:资源只能给浏览器缓存,不能给代理服务器缓存
强缓存
强缓存步骤:
- 第一次请求 a.js ,缓存表中没该信息,直接请求后端服务器。
- 后端服务器返回了 a.js ,且 http Response Header中 cache-control 为 max-age=xxxx,所以是强缓存规则,存入缓存表中。
- 第二次请求 a.js ,缓存表中是max-age, 那么命中强缓存,然后判断是否过期,如果没过期,直接读缓存的a.js,如果过期了,则执行协商缓存的步骤了。
max-age=0和no-cache的区别:max-age是进行强缓存,但过期了,走协商缓存;no-cache是直接走协商缓存。两者效果一样。
协商缓存
协商缓存无论如何都是会向服务器发送请求的,只不过,资源未更改时,返回的只是header信息,所以size很小;而资源有更改时,还要返回body数据,所以size会大。
触发条件:1,强缓存(max-age)过期;2,Cache-Control值为no-cache(不强缓存)
每次http返回来 response header 中的 (每个文件都有一个,改动文件时ETag会变)和 Last-Modified(文件的修改时间),在下次请求时在 request header 就把这两个标识带上(但是名字变了ETag–>If-None-Match,Last-Modified–>If-Modified-Since ),服务端把带过来的标识,资源目前的标识,进行对比,然后判断资源是否更改了。 如果资源没更改,返回304,浏览器读取本地缓存;如果资源有更改,返回200,返回最新的资源和最新的标识。
协商缓存步骤:
有了Last-Modified,为什么还要有ETag?
主要是为了解决几个Last-Modified比较难解决的问题:
- 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变了修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),Last-Modified能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
- 某些服务器不能精确的得到文件的最后修改时间。
用户行为对缓存的影响?
F5 会跳过强缓存规则,直接走协商缓存;Ctrl+F5 ,跳过所有缓存规则,和第一次请求一样,重新获取资源。
为什么很多站点第二次打开速度会很快?
如果第二次页面打开很快,主要原因是第一次加载页面过程中,缓存了一些耗时的数据。
那么,哪些数据会被缓存呢?从上面介绍的核心请求路径可以发现,DNS 缓存和页面资源缓存这两块数据是会被浏览器缓存的。DNS 缓存主要就是在浏览器本地把对应的 IP 和域名关联起来。
简要来说,很多网站第二次访问能够秒开,是因为这些网站把很多资源都缓存在了本地,浏览器缓存直接使用本地副本来回应请求,而不会产生真实的网络请求,从而节省了时间。同时,DNS 数据也被浏览器缓存了,这又省去了 DNS 查询环节。
如果一个页面的网络加载时间过久,你是如何分析卡在哪个阶段的?
1 首先猜测最可能的出问题的地方,网络传输丢包比较严重,需要不断重传。然后通过ping curl看看对应的时延高不高。
2 然后通过wireshake看看具体哪里出了问题。
3 假如别人访问很快,自己电脑很慢,就要看看自己客户端是否有问题了。