菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
269
0

缓存

原创
05/13 14:22
阅读数 66632

1. 位置

我们浏览器查找缓存会有优先级:

1. Service Worker

2. Memory Cache

3. Disk Cache

4. Push Cache

5. 网络请求

Service Worker

在上一篇博文,我们已经介绍过Service Worker,我们可以利用。

如果我们定义了Service Worker,那么,所有请求都先走它。

如果 Service Worker 的缓存不能命中,那么就会通过 fetch 发出请求。

而 fetch 会先依次尝试查找各个缓存。

Memory Cache

Memory Cache,顾名思义是存到内存的缓存,这里的缓存当然非常快。一般小文件会缓存到这,,同时缓存到 Disk Cache。

页面被关闭前,再次访问都会访问 Memory Cache。

如果页面被关闭,Memory Cache 就会被释放,然后下次打开就会访问 Disk Cache。

Disk Cache

Disk Cache,就是缓存到硬盘,这个会比 Memory Cache 慢一些,但是时效性强。一般大文件首次加载就缓存到这。

 

Push Cache

这个是 HTTP 2 的一个特性,博主也不怎么了解,就不误人子弟了。

推荐阅读:https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/

网络请求

最后实在没办法了,就只能真发出去请求,去获取资源了。

 

2. 策略

缓存策略分为2种:强缓存协商缓存, 都是通过 http header 来实现的。

强缓存

通过 Expires 和 Cache-control 来实现。

Expires 是 HTTP 1.0 的产物,例如

Expires: Wed, 22 Oct 2018 08:41:00 GMT

表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

 

Cache-control 是 HTTP 1.1 的产物,优先级高于 Expires ,例如

Cache-control: max-age=30

表示该资源会在 30 秒后过期,需要再次请求。

其中很重要的2个属性 max-ageno-cache

max-age 指定缓存生效的时间,时间过去才会失效;no-cache 会缓存,但是马上失效,以后都会进行协商缓存

至于 Cache-control 还有什么值,详细请看我之前写过的博文:点击查看

 

协商缓存

协商缓存是出现在缓存失效的时候,它是通过 Last-Modified, If-Modified-Since  和 Etag, If-None-Match 来实现的。

Last-Modified 和 If-Modified-Since 是 HTTP 1.0 的产物,表示文件最后修改日期。

If-Modified-Since 会将 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,否则返回 304 状态码。

但是它会有些弊端:

1. 以秒为单位,如果 1s 内修改了好几次,这就无法感知到了。

2. 如果一个文件只是打开保存,并没有修改,但是服务器还是认为被修改了。

 

Etag If-None-Match 是 HTTP 1.1 的产物,是为了解决 Last-Modified 的问题而出现的,优先级比 Last-Modified 高,相当文件的一个特征值(例如文件的md5)

If-None-Match 会将 Etag 的值发给服务器,询问服务器文件的特征值是否和发过来的一致,如果不一致说明文件更新了,返回新的资源,否则返回304。

 

3.默认缓存时间

如果文件没设置强缓存的缓存策略,那浏览器会用 Date - Last-Modified 的时间的 10% 作为缓存时间。

意思大概是,更新时间越古老的文件,缓存时间越长。

 

4. 实际使用

频繁修改的文件:  Cache-control: no-cache,每次请求都采用协商缓存。

代码文件:Cache-control: max-age=31536000,代码文件缓存一直缓存,因为一般webpack打包后都会修改文件名,后面跟着一串hash

 

发表评论

0/200
269 点赞
0 评论
收藏