小小狐狸 2019-06-30
对浏览器缓存这一块一直是乱哄哄的状态,今天终于有时间整理一下,写下这篇笔记,以供日后查阅。
良好的缓存策略可以降低资源的重复加载提高网页的整体加载速度
通常浏览器缓存策略分为两种:强缓存和协商缓存
如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;
强缓存不发请求到服务器,协商缓存会发请求到服务器。
强缓存通过Expires和Cache-Control两种响应头实现
Expires是http1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回。
Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效
Expires: Sat, 29 Sep 2018 14:20:00 GMT
Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires ,表示的是相对时间
Cache-Control: max-age=315360000
Cache-Control在request和response中都可以使用
当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的http状态为304并且会显示一个Not Modified的字符串
协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对Header来管理的
Last-Modified 表示请求来的文件的最后修改日期,浏览器会在request header加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。
Etag就像一个指纹,资源变化都会导致ETag变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的
If-None-Match的header会将上次返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变动就会发送新的资源回来
ETag的优先级比Last-Modified更高
首先Last-Modified在http/1.0中被提出,而在http/1.1中提出的ETag则是为了解决Last-Modified无法解决的一些问题
一些图片等静态文件的修改,如果每次扫描内容生成 ETag 来比较,显然要比直接比较修改时间慢很多
所以说两者并不是互斥,而是相辅相成的关系,既可以单独使用,又可以同时使用。
同时传入服务器时,服务器可以根据自己的缓存机制的需要,选择ETag或者是Last-Modified来做缓存判断的依据,甚至可以两个同时参考。
协商缓存需要配合强缓存使用,如果不启用强缓存的话,协商缓存根本没有意义
大部分web服务器都默认开启协商缓存,而且是同时启用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】
Apache对于静态内容默认会返回Last-modified和ETag.Nginx只会返回Last-modified(可配置etag on开启).
但是下面的场景需要注意:
https://github.com/amandakela...
https://blog.csdn.net/u012375...
https://segmentfault.com/q/10...
baidu and google