一、浏览器缓存简介
- 1、浏览器通过缓存服务器返回的资源(针对静态资源和get请求),减少传输压力,提高访问速度。
- 2、那么缓存的目标应该是:资源可以被缓存 + 保证不使用过期的资源 + 服务器资源部分更新的时候不能导致新旧文件内容不一致。所以可以结合实际情况,设置适当的缓存策略。
- 3、浏览器无缓存的过程:
浏览器请求 ---> 无缓存 ---> 请求WEB服务器 ---> 请求响应 ---> 呈现 4、浏览器有缓存的过程:
浏览器请求 ---> 有缓存 ---> 校验过期(无需发请求) ---> 是否有更新(需要发请求,结合Etag或Last-Modified验证更新) ---> 呈现二、常见缓存策略
http本身是个协议,缓存是浏览器实现的。可以通过设置或读取HTTP头来实现对应的缓存机制(强缓存和协商缓存)。
1、 强缓存策略(可以强制缓存并定义足够长的过期时间让资源在本地长期驻留,但是不能及时更新):Cache-Control和Expire
- Cache-Control:max-age 的优先级要比Expires高。若命中,则不向服务器发请求。
- Expires有弊端:是绝对时间,依赖客户端时间,可能和服务端时间不一致。
2、协商缓存(用于检测新鲜度,协商缓存能够保证及时更新,但是会频繁地去服务器验证,浪费性能):Etag(和If-None-Match一对) 和 Last-Modified(和If-Modified-Since一对);每次都要向服务器get请求验证。
Last-Modified有缺陷:
- (1)只是编辑了文件,但是文件内容没有变化,Last-Modified也会改变
- (2)Last-Modified只能精确到s,如果文件操作在ms级操作,则精确不到
Etag根据文件内容生成hash(通常最终的 ETag 将由实体的长度和哈希值两部分组成。),更精确,也有缺陷:
- (1)服务器计算etag需要额外的性能开销
- (2)分强验证(每个字节都相同)和弱验证(部分字节相同),要根据具体的业务场景合理选择。
3、缓存优先级:
Cache-Control(强) > Expires (强)> Etag / If-None-Match > Last-Modified / If-Modified-Since
三、实践
index.html入口资源:
- 要保证及时更新,可设置协商缓存,cache-control: no-cache
cdn上的资源
- 如vue,不经常变动,路径中有版本号,可以设置很长的时间,如cache-control: max-age=31536000(一年)
- cdn上的配置文件,有可能会很快变化,有可能也不快,可设置cache-control: max-age=86400(一天)(可用cdn的主动刷新机制)
图片,视频等资源
- 不经常更改且占用缓存空间大,可设置强缓存且过期时间不宜太长,如cache-control: max-age=86400(一天)
项目的业务CSS和JS等资源
- 内容可能不定期修改,可结合webpack生成带hash的文件,如style.51af3464.css。如果文件内容变了,打包后的hash也会变,url就会变,浏览器会重新请求,所以过期时间可以很长。如cache-control: max-age=31536000(一年)
JS脚本文件:如果js资源中包含私人信息,则不能让中间代理缓存,则要为cache-control添加private
四、示例
1、无缓存no-cache
五、用户行为对浏览器缓存的影响
所谓用户行为对浏览器缓存的影响,指的就是用户在浏览器如何操作时,会触发怎样的缓存策略。主要有 3 种:
- 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
- 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。
- 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。