目录
注意:浏览器缓存与浏览器本地存储不是同一个概念!!
一、为什么需要浏览器缓存
所谓的浏览器缓存指的是浏览器将用户请求过的静态资源,存储到电脑本地磁盘中,当浏览器再次访问时,就可以直接从本地加载,不需要再去服务端请求了。
使用浏览器缓存,有以下优点:
- 减少了服务器的负担,提高了网站的性能
- 加快了客户端网页的加载速度
- 减少了多余网络数据传输
二、资源缓存的位置
1. Service Worker:Service Worker 运行在 JavaScript 主线程之外,虽然由于脱离了浏览器窗体无法直接访问 DOM,但是它可以完成离线缓存、消息推送、网络代理等功能。
2. Memory Cache: Memory Cache 就是内存缓存,它的效率最快,但是内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
3. Disk Cache: Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比起 Memory Cache 胜在容量和存储时效性上。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。
三、缓存策略
强制缓存优先于协商缓存进行,若强制缓存生效则直接使用缓存,若不生效则进行协商缓存,协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回 200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回 304,继续使用缓存。
1. 强缓存
不会向服务器发起请求,如果缓存资源有效,直接使用缓存资源。通过设置http 头信息中的 Expires 或 Cache-Control 属性。
(1)服务器在响应头中添加 Expires 属性,来指定资源的过期时间,该时间是服务端的具体时间,受限于本地时间:如果改变本地客户端的时间导致和服务器端的时间不一致,就可能会影响缓存命中。
(2)Expires 是 http1.0 中的方式,因为它的一些缺点,在 HTTP 1.1 中提出了Cache-Control 属性,它提供了对资源的缓存的更精确的控制:谁可以缓存响(public 与 private ),怎么缓存(no-cache,no-store)以及可以缓存多久(max-age)。
2. 协商缓存
强缓存只管缓存是否过期,而不关心服务端文件是否已经更新,这可能会导致加载的资源不是服务端最新的内容。如果命中强制缓存,直接使用缓存内容;否则进行协商缓存,命中协商缓存的条件有是Cache-Control的:
max-age=xxx
过期了- 值为
no-store
此时,使用协商缓存策略,浏览器会向服务器发送一个请求,如果资源没有发生修改,则返回 304 让浏览器使用本地的缓存;如果资源发生了修改,则返回200修改后的资源。
协商缓存的实现通过设置http 头信息中的Last-Modified和Etag (优先级更高,更准,但低效点(负载平衡))属性:
(1)浏览器在第一次返回资源时,在响应头中添加 Last-Modified 值是该资源在服务器上的最后的修改时间,浏览器下一次请求该资源时,请求头中会添加 If-Modified-Since值就是 该Last-Modified 的值,而服务端会将其与服务器中该资源的最后修改时间对比,如果If-Modified-Since小,则说明资源有更新则返回200和新资源。【Last-Modified 只能以秒计,若一秒内修改了资源,则感知不到】
(2)ETag 是服务器响应请求时返回资源文件的唯一标识,只要资源有变化 ETag 就会重新生成。浏览器在下发送请求时,会将上一次返回的 Etag 值放到 If-None-Match 里,服务器将其跟自己资源的 ETag 进行比较,就可判断资源相对客户端而言是否被修改过。
3. 无缓存策略
4. 如果没设置缓存策略:浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。
4.用户行为影响
- 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
- 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先匹配使用,其次是 disk cache。
- 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache,服务器直接返回 200 和最新内容。