跳到主要内容

浏览器缓存

· 阅读需 7 分钟
多云转晴
前端开发

浏览器的缓存类型比较多,例如:

  • HTTP Cache: HTTP 缓存;
  • Disk Cache: 将缓存写入到硬盘中;
  • Memory Cache: 将缓存写入到内存中;
  • Service Worker Cache;

强缓存

Disk CacheMemory Cache 属于强缓存,是 HTTP 缓存的产物,强缓存的产生依赖于请求响应中的 cache-controlexpires 的 headers 字段。这两个字段都用来设置缓存数据的有效时间。

强缓存

当请求响应符合强缓存时,浏览器会根据 header 头中的字段类型进行缓存处理。通常情况下:

  • Memory Cache: 会存放脚本、base64数据和字体等;
  • Disk Cache: 会存放样式文件、图片或比较大的文件等;

此行为属于浏览器行为,服务器不可对其进行控制

内存缓存和硬盘缓存两者的区别:

内容缓存强缓存
Disk Cache长期存在,关闭浏览器后同样存在;存储文件空间很大
Memory Cache短期存储,生命周期是会话级的,会话结束后将清除缓存;访问速度快、优先级高

强缓存

协商缓存

当强缓存失效后,浏览器就会携带缓存标志向服务器发送请求。主要用到的 header:

  • Etag / If-None-Match
  • Last-Modified / If-Modified-Since

当收到请求的响应时,会携带:

  • Etag:服务器基于某种规则对资源生成的一个标志,类似于文件 hash。
  • Last-Modified:服务器返回的文件最后修改的时间。

当发送请求的时候,浏览器会携带:

  • If-None-Match:对应的是 Etag 的值。
  • If-Modified-Since:对应的是 Last-Modified 的值。

服务器根据这两个值进行匹配,如果相等,说明文件没有变化,返回 304,浏览器直接从缓存里面取;当不相等时,服务器发送最新的内容,状态码为 200。

协商缓存

301 和 304 状态码

  • 301(Moved Permanently)当服务器返回301状态码时,表示被请求的资源已永久移动到了一个新的URL地址。客户端收到301响应后,会自动重定向到新的URL地址。搜索引擎会将原始URL的排名和索引等信息转移到新的URL上。因此,301重定向适用于资源永久性更改的情况。
  • 304(Not Modified)当服务器返回304状态码时,表示客户端缓存的资源仍然有效,并且没有发生修改。这时,服务器不会返回实际的资源内容,而是告诉客户端可以直接使用本地缓存的版本。这样可以减少网络流量和服务器负载,提高性能。

区别

  1. 301是永久重定向,要求客户端将请求的URL更新为新的URL,而304是缓存验证,告诉客户端可以使用本地缓存的版本。
  2. 301会导致客户端发起新的请求,而304不会发起新的请求,直接使用本地缓存。
  3. 301适用于资源永久移动的情况,而304适用于资源未被修改的情况。
  4. 301会改变搜索引擎对URL的索引,而304不会改变搜索引擎的索引。

应用场景

301:

  1. 网站重定向:当网站的URL结构发生变化或网站迁移时,可以使用301重定向将旧的URL重定向到新的URL,以保持搜索引擎的排名和用户的访问流量。
  2. 域名重定向:当网站更换域名时,可以使用301重定向将旧域名的请求重定向到新域名,以确保用户能够访问到正确的网站。
  3. 移动设备重定向:当网站有适用于移动设备的版本时,可以使用301重定向将桌面版本的URL重定向到移动版本的URL,以提供更好的移动用户体验。

304:

  1. 浏览器缓存验证:客户端在发送请求时会附带上资源的缓存标识(如 ETagLast-Modified 时间)。服务器可以使用304状态码来告诉客户端,资源未被修改,可以直接使用本地缓存,避免重新传输资源。
  2. 静态资源缓存:服务器可以使用304状态码配合缓存机制,使客户端在缓存有效期内直接使用本地缓存,减少网络流量和服务器负载。
  3. 加速CDN内容分发:当使用内容分发网络(CDN)时,CDN服务器可以使用304状态码来验证缓存的内容是否有效,避免不必要的数据传输。

Service Worker Cache

该缓存属于 PWA Cache Storage API,它有更精细的通过程序操作缓存的能力。缓存命中条件依赖于 fetch,是否从 ServiceWorker Cache 里面取缓存,完全依赖于 ServiceWorker 的脚本控制,这取决于用户的自定义设置。

service-worker file

Service Worker Cache

浏览器刷新操作

在浏览器上进行不同的刷新操作,所发送的实际请求也是不同的。

操作强缓存Service Worker Cache协商缓存缓存 Headers 变动
刷新按钮或 Cmd+R有效有效有效无变动
Cmd+Shift+R无效无效无效请求中无 If-None-Match/If-Modified-Since。
Cache-Control 的值为 no-cache
DevTools Network 面板开启 Disable Cache无效无效无效同上,但无缓存时的能力更强

可以使用 Charles 等抓包工具实验一下,例如找一个 Service Worker Cache 的资源文件,在第二次刷新页面时对应的三种操作是否发起了网络请求。

SessionStorage 和 LocalStorage

区别:

  1. 生命周期和作用域:

    • SessionStorage:存储在 SessionStorage 中的数据仅在当前会话期间有效。当用户关闭浏览器标签页或窗口时,会话结束,SessionStorage 中的数据也会被清除。数据的作用域限定在当前会话中的页面或标签页。
    • LocalStorage:LocalStorage 中的数据是持久化的,除非被显式删除,否则会一直存在。即使用户关闭浏览器或重新启动计算机,数据也不会丢失。数据的作用域限定在同一域名下的所有页面。
  2. 存储容量:

    • SessionStorage:SessionStorage 的存储容量通常较小,一般为 5MB 到 10MB。
    • LocalStorage:LocalStorage 的存储容量较大,一般为 5MB 到 20MB。
  3. 数据共享:

    • SessionStorage:SessionStorage 中的数据不会被不同的浏览器标签页或窗口共享。每个标签页/窗口都有自己独立的SessionStorage。
    • LocalStorage:LocalStorage 中的数据在同一域名下的所有页面之间是共享的。不同的浏览器标签页或窗口可以访问和修改同一个 LocalStorage 中的数据。

如果需要在会话期间保存数据,且该数据不需要在不同标签页或窗口之间共享,则使用 SessionStorage。
如果需要在长时间内保存数据,或者需要在不同标签页或窗口之间共享数据,则使用 LocalStorage。

除了使用 LocalStorage 持久化存储数据外,也可以使用 IndexedDBCookies(通常为4KB存储大小) 、FileSystem API(兼容性差)、WebSQL(已废弃,兼容性差)等 API。