一个网站设置缓存是必不可少的,网站开发中,有很多资源是不会经常更新,这些资源在用户第一次访问网站的时候缓存到本地后,当用户第二次重新进入网站时直接使用本地缓存里的资源去渲染页面,无需再去服务器请求资源,会更加快速的让用户浏览到网页,还可以减少http请求数量,缓存分为强缓存和协商缓存。
随便打开一个网站,观察浏览器中network中的资源加载情况(Chrome浏览器)
状态 | 类型 | 说明 |
---|---|---|
200 | form memory cache | 不请求网络资源,资源在内存当中,一般脚本、字体、图片会存在内存当中 |
200 | from dist cache | 不请求网络资源,在磁盘当中,一般非脚本会存在内存当中,如css等 |
200 | 资源大小数值 | 从服务器下载最新资源 |
304 | 报文大小 | 报文大小 请求服务端发现资源没更新,使用本地资源 |
强缓存:
强缓存有Expires和Cache-Control两个字段。
1、Expires
该字段是利用http1.0时的规范,他的值为一个绝对时间的GMT格式的时间字符串,这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
2、Cache-Control
Cache-Control是http1.1时出现的header信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如Cache-Control:max-age=3600,代表着资源的有效期是3600秒。Cache-Control除了该字段外,还有下面几个比较常用的:
类型 | 说明 |
---|---|
no-cache | 不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。 |
no-store | 直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。 |
public | 可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。 |
private | 只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。 |
immutable | 如果有请求该资源的需求的话就直接读取缓存,即使用户做了刷新操作,也不向服务器发起http请求。 |
Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高。
3、from memory cache 和 from disk cache区别:
下方图片是一个存在磁盘中的资源的请求头详情
下方图片是一个存在缓存中的资源的请求头详情
from memory cache: 字面理解是从内存中,其实也是字面的含义,这个资源是直接从内存中拿到的,不会请求服务器一般已经加载过该资源且缓存在了内存当中,当关闭该页面时,此资源就被内存释放掉了,再次重新打开相同页面时不会出现from memory cache的情况;
from disk cache: 同上类似,此资源是从磁盘当中取出的,也是在已经在之前的某个时间加载过该资源,不会请求服务器但是此资源不会随着该页面的关闭而释放掉,因为是存在硬盘当中的,下次打开仍会from disk cache;
由此可见样式表一般在磁盘中,不会缓存到内存中去,因为css样式加载一次即可渲染出网页,但是脚本却可能随时会执行,如果脚本在磁盘当中,在执行该脚本需要从磁盘中取到内存当中来,这样的IO开销是比较大的,有可能会导致浏览器失去响应。
协商缓存:
状态码为304,先去发起请求问服务器是否走缓存,服务器告知走缓存后,则会从缓存中读取资源;
1、Etag 和 If-None-Match:
加载资源的时候,服务器返回到response header中,是对该资源的唯一标识,该资源如果有改动,则会重新生成Etag;浏览器在下一次加载资源的时候,会将上一次保存的Etag放在request header里的If-None-Match,发给服务器,服务器接收到,会和该资源文件的Etag做比较,如果相同则表示资源没有改变,走缓存;
2、Last-modified 和 If-Modified-Since:
Last-modified 是该文件最后一次的修改时间,服务器会在response header中返回;浏览器会保存该值;下一次再发起该请求,会将保存的这个值从request header中的If-Modified-Since中发给服务器,服务器接收到就会对比,如果相同,就返回304。
3、两者对比
在精确度上,Etag要优于Last-Modified,Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度
在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而 注:Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
强缓存 VS 协商缓存:
最好是配合在一起用,争取最大化的减少请求,利用缓存,节约流量。