浏览器的缓存策略

1.什么是浏览器的缓存策略

  1. 浏览器缓存策略是现代Web开发中一项关键性能优化手段,旨在减少网络延迟、降低服务器负载以及提升用户访问速度。浏览器通过缓存策略存储网页中的静态资源,并在后续访问时尽可能地复用这些已缓存的内容,而非每次都向服务器发起新的请求。
  2. 优点:
    • 直接从内存或磁盘中取缓存数据能加快客户端网页加载速度,减少用户等待时间,提升用户体验。
    • 减少了冗余的数据传输,减少服务器的负担,提升网站性能。

2. 缓存位置与优先级

  1. 离线缓存Service Worker cache 。(详情看后续文章)
  2. 浏览器内存缓存memory cache
    • 相比于硬盘缓存,它的特点是读取速度快,但容量小,且时效性短。一旦浏览器tab页关闭,浏览器内存缓存就将被清空,再次重新打开相同页面时不再出现from memory cache的情况。
    • 不受开发者控制,也不受HTTP协议头的约束,但是当HTTP响应头设置了Cache-Control: no-store的时候或者浏览器开发者工具network设置了Disabled cache禁用缓存后,就无法把资源存入浏览器内存了,也无法存入硬盘
    • 当从浏览器内存缓存中查找缓存的时候,不仅仅会去匹配资源的URL,还会看其Content-type 是否相同。
  3. 硬盘缓存disk cache
    • 从存储效率上讲是浏览器内存缓存慢的,但是优势是存储容量大和存储时间长。
    • 可以根据HTTP响应头的各类字段进行判定资源的缓存规则,比如是否可以缓存,什么时候过期,过期之后是否需要重新发起请求
  4. 文件会先在浏览器内存缓存中查找,如果有,直接加载。 如果不存在,则在硬盘缓存中查找,如果有直接加载。 如果硬盘缓存中也没有,则向服务器发起网络请求。请求获取的资源缓存到硬盘和内存。
  5. 浏览器内存缓存适合存储脚本文件图片文件等,硬盘缓存适合存储CSS文件。CSS文件加载一次就可渲染出来,不会频繁读取它,所以它不适合缓存到内存中,但是脚本却随时可能会执行,当执行脚本的时候需要从硬盘取到内存中来,这样IO开销就很大。

3. 强缓存与协商缓存

强缓存

  1. 强缓存是一种完全基于客户端缓存数据来决定是否使用缓存的策略。当浏览器发起一个资源请求时,首先检查是否有对应的强缓存数据存在,并依据以ExpiresCache-Control的响应头部信息判断缓存是否有效,有效的话是的话便直接从本地缓存中读取资源,不与服务器进行通信。
  2. 同时设置了两个字段的适合时候,Cache-Control优先级比Expires高。

Expires

  1. HTTP/1.0时代的头部字段,它设置了一个绝对的GMT日期时间,表示资源的过期时间。
  2. 若当前时间在此之前,浏览器认为缓存有效,反之则无效。由于其依赖于客户端系统时间可能与服务器设置的时间可能存在误差,现代应用中逐渐被Cache-Control取代。
js 复制代码
Expires: Mon Oct 17 2023 16:10:32 GMT

Cache-Control

  1. HTTP/1.1标准中定义的响应头部字段,用于更精确地控制缓存行为。
  2. Cache-Control: max-age=<seconds>:用来指定资源的最大存活时间(以秒为单位)。在此期间内,浏览器认为缓存有效,无需向服务器验证,直接使用本地缓存响应请求。超过这个时间后,浏览器将重新发起请求。
  3. Cache-Control: no-store:禁止缓存任,所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存。
  4. Cache-Control: public:所有内容都可被缓存。
  5. Cache-Control: private:所有内容只有客户端可以缓存,Cache-Control的默认取值。
  6. Cache-Control: s-maxage=<seconds>:对于共享缓存而言,优先于max-age。仅适用于代理服务器。
  7. Cache-Control: no-cache:缓存不直接使用,是否使用缓存则需要经过协商缓存来验证决定。除了此选项其他的都是强缓存,强缓存失效的情况下会使用协商缓存。
  8. 强制缓存返回的状态值是200size下会显示两种字段,from memory cache代表使用浏览器内存中的缓存。from disk cache则代表使用的是硬盘中的缓存。

协商缓存

  1. 协商缓存发生在强缓存失效或未命中时,浏览器向服务器询问现有缓存资源是否仍然有效。如果强缓存失效后,客户端将向服务器发出请求,进行协商缓存。
  2. 浏览器会自动携带上一次请求返回的响应头中的 缓存标识 向服务器发起请求ETag、Last-Modified,由服务器判断资源是否更新。
  3. 如果资源没有更新,则返回状态码304 Not Modified,告诉浏览器可以使用本地缓存;否则返回新的资源内容。
  4. 强缓存优先级高于协商缓存,但是协商缓存可以更加灵活地控制缓存的有效性。

ETag/If-None-Match

  1. ETag是服务器为每个资源生成的一个唯一标识符(通常基于内容哈希或其他算法),随响应头一起发送给客户端。
  2. 当浏览器再次请求时,浏览器会在请求头附带上If-None-Match头部,其值为之前接收到的ETag
  3. 服务器比较请求中的If-None-Match与当前资源的ETag,如果二者匹配,则说明资源内容没有变化,服务器返回304 Not Modified状态码,使用本地缓存。

Last-Modified/If-Modified-Since

  1. Last-Modified是服务器指示资源最后修改时间的头部字段。第一次请求是服务器响应头中携带Last-Modified时间。
  2. 浏览器在后续请求中自动携带If-Modified-Since头部,其值为之前接收到的Last-Modified
  3. 服务器比较请求头中的If-Modified-Since与当前资源的最后修改时间,如果Last-Modified晚于If-Modified-Since,说明资源已被更新,服务器返回新资源和200 OK状态码;否则返回304 Not Modified

4. 缓存执行过程

  1. 强缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,返回状态码为200
  2. 强缓存失效或未命中,浏览器向服务器发起请求。请求头中包含If-None-Match(基于ETag)或If-Modified-Since(基于Last-Modified)头部,进行协商缓存。
  3. 服务器接收到请求,比较条件头与当前资源的状态,若资源未发生变化,服务器返回304 Not Modified,浏览器使用本地缓存。若资源已更新,服务器返回新资源状态码200 OK及新的ETagLast-Modified,浏览器更新缓存并使用新资源。

5. 总结

  1. 在实际应用中,可能同时采用强缓存和协商缓存策略。浏览器优先考虑强缓存,只有当强缓存失效或无法满足时,会进入协商缓存阶段,向服务器发起条件请求。
  2. 这样设计的原因在于强缓存能够避免不必要的网络通信,提供最快捷的响应体验。而协商缓存虽然仍需与服务器通信,但只需少量数据交换即可确定缓存的有效性,相比完全重新下载资源,仍能显著节省带宽和提高性能。
  3. 浏览器的缓存策略通过强缓存和协商缓存相结合的方式,有效地利用客户端存储减少网络交互,优化网页加载速度。
相关推荐
安冬的码畜日常9 分钟前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n037 分钟前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。1 小时前
案例-任务清单
前端·javascript·css
zqx_72 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己2 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称3 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2343 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河3 小时前
CSS总结
前端·css
BigYe程普4 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发