关于javascript:深入07-浏览器缓存机制http缓存机制

8次阅读

共计 6432 个字符,预计需要花费 17 分钟才能阅读完成。

导航

[[深刻 01] 执行上下文 ](https://juejin.im/post/684490…
[[深刻 02] 原型链 ](https://juejin.im/post/684490…
[[深刻 03] 继承 ](https://juejin.im/post/684490…
[[深刻 04] 事件循环 ](https://juejin.im/post/684490…
[[深刻 05] 柯里化 偏函数 函数记忆 ](https://juejin.im/post/684490…
[[深刻 06] 隐式转换 和 运算符 ](https://juejin.im/post/684490…
[[深刻 07] 浏览器缓存机制(http 缓存机制)](https://juejin.im/post/684490…
[[深刻 08] 前端平安 ](https://juejin.im/post/684490…
[[深刻 09] 深浅拷贝 ](https://juejin.im/post/684490…
[[深刻 10] Debounce Throttle](https://juejin.im/post/684490…
[[深刻 11] 前端路由 ](https://juejin.im/post/684490…
[[深刻 12] 前端模块化 ](https://juejin.im/post/684490…
[[深刻 13] 观察者模式 公布订阅模式 双向数据绑定 ](https://juejin.im/post/684490…
[[深刻 14] canvas](https://juejin.im/post/684490…
[[深刻 15] webSocket](https://juejin.im/post/684490…
[[深刻 16] webpack](https://juejin.im/post/684490…
[[深刻 17] http 和 https](https://juejin.im/post/684490…
[[深刻 18] CSS-interview](https://juejin.im/post/684490…
[[深刻 19] 手写 Promise](https://juejin.im/post/684490…
[[深刻 20] 手写函数 ](https://juejin.im/post/684490…

[[react] Hooks](https://juejin.im/post/684490…

[[部署 01] Nginx](https://juejin.im/post/684490…
[[部署 02] Docker 部署 vue 我的项目 ](https://juejin.im/post/684490…
[[部署 03] gitlab-CI](https://juejin.im/post/684490…

[[源码 -webpack01- 前置常识] AST 形象语法树 ](https://juejin.im/post/684490…
[[源码 -webpack02- 前置常识] Tapable](https://juejin.im/post/684490…
[[源码 -webpack03] 手写 webpack – compiler 简略编译流程 ](https://juejin.im/post/684490…
[[源码] Redux React-Redux01](https://juejin.im/post/684490…
[[源码] axios ](https://juejin.im/post/684490…
[[源码] vuex ](https://juejin.im/post/684490…
[[源码 -vue01] data 响应式 和 初始化渲染 ](https://juejin.im/post/684490…
[[源码 -vue02] computed 响应式 – 初始化,拜访,更新过程 ](https://juejin.im/post/684490…

缓存的重要性

  • 一个优良的缓存策略,能够缩短网页申请资源的间隔,缩小提早,缓存文件能够反复利用所以还能够缩小带宽,升高网路负荷

浏览器缓存

  • 浏览器启用缓存的长处:缩小页面加载工夫,缩小服务器负载
  • <font color=red> 浏览器是否应用缓存,缓存多久,是由服务器管制的 </font>

    • 即服务器响应的 <font color=red> 响应头 </font> 中,某些字段指明了缓存的要害信息
  • 通用首部字段

    • 申请和响应都能用的字段
    • Cache-Control
  • 申请首部字段

    • If-None-Match
    • If-Modified-Since
  • 响应首部字段

    • ETag
  • 实体首部字段

    • Expires
    • Last-Modified
  • 浏览器缓存的分类

    • <font color=red> 强缓存 </font> 和 <font color=red> 协商缓存 </font>

强缓存

  • <font color=red>Expires</font>,<font color=red>Cache-Control</font>
  • 返回的状态码 200
  • <font color=red>network => size => 会显示 from-cache (from-disk-cache),(from-memory-cache) </font>
  • 强缓存的实现:通过 (<font color=red>Expires</font>) 或者 (<font color=red>Cache-Control</font>) 这两个 (<font color=red>http response header</font>) 来实现的,他们用都是用来示意资源在客服端存在的 <font color=red> 有效期 </font>

Expires

  • http1.0 提出,响应头中的一个字段,相对工夫,用 GMT 格局的字符串示意
  • <font color=red> 留神:expires 是和浏览器本地的工夫做比照,是一个相对工夫点,是一个 GMT 工夫 </font>
  • Expires 是优化中最现实的状况,因为它基本不会产生申请,所以后端也就无需思考查问快慢
  • Expires 的原理

    Expires 的原理 
  • 浏览器第一次向服务器申请资源,浏览器在申请资源的同时,在 responder 响应头中加上 Expires 字段
  • 浏览器在接管到这个资源后,将这个资源和所有 response header 一起缓存起来

    • 所以,缓存命中的申请返回的 header 并不是来自服务器,而是来自之前缓存的 header
  • 浏览器再次申请这个资源时,先从缓存中寻找,找到这个资源后,拿出 Expires 跟以后的申请工夫做比拟

    • 如果以后申请工夫,在 Expires 指定的工夫之前,就能命中强缓存,否则不能
    • 留神:Expires 是和浏览器本地工夫作比照
  • 如果未命中缓存,则浏览器间接从服务器获取资源,并更新 response header 中的 Expires

  • expires 是较老的强缓存治理 header,<font color=red> 是服务器返回的一个相对工夫 </font>,在服务器工夫与客服端工夫相差较大时,Expires 缓存治理容易出问题(比方:轻易批改客户端工夫,就能影响命中后果),所以在 http1.1 中,提出了新的 header => Cache-Control,一个绝对工夫,以秒为单位,用数值示意

Cache-Control

  • http1.1 提出,响应头中的一个字段,绝对工夫,以秒为单位,用数值示意
  • <font color=red> 留神:Cache-Control 也是和浏览器本地工夫做比照,以秒为单位的时间段 </font>
  • Cache-Control 能够指定:<font color=red>public</font> 和 <font color=red>private</font>

    • <font color=red>private</font>: 示意该资源仅仅属于发出请求的最终用户,这将禁止两头服务器(如代理服务器)缓存此类资源,对于蕴含用户个人信息的文件,能够设置 private
    • <font color=red>public</font>: 容许所有服务器缓存该资源
    • no-cache:应用协商缓存
    • no-store:不应用缓存
    • max-age: 123123 // 一个时间段,单位是 s
  • <font color=red>Cache-control: no-cache,private,max-age=123123</font>
  • Cache-Control 的原理
Cache-Control 的原理

1. 浏览器第一次向服务器申请资源,服务器在返回资源的同时,在 responder 的 header 中加上 Cache-Control 字段
2. 浏览器在接管到这个资源后,会将这个资源和所有的 response header 一起缓存起来
   - 所以,缓存命中的申请返回的 header 并不是来自服务器,而是来自之前缓存的 header
3. 浏览器再次申请这个资源时,先从缓存中寻找,找到这个资源后,拿出 Cache-Control 和以后申请的工夫做比拟
   - 如果以后申请工夫,在 Cache-Control 示意的时间段内,就能命中强缓存,否则不能
4. 如果缓存未命中,则浏览器间接从服务器获取资源,并更新 response header 中的 Cache-Control

强缓存 Expires 和 Cache-Control 总结

  • Expires 和 Cache-Control 能够开启一个,也能够同时开启
  • 当 Expires 和 Cache-Control 同时开启时,Cache-Control 优先级高于 Expires
  • Cache-Control 能够指定 private 和 public,示意是否容许两头服务器缓存该资源
  • expires 是一个用 GMT 工夫示意的工夫点,Cach-Control 是用秒示意的时间段,都是和浏览器本地工夫做比照

协商缓存

  • <font color=red>Last-Modified(If-Modified-Since)</font>,<font color=red>ETag(If-None-Match)</font>
  • 返回状态码 304
  • 协商缓存的原理:<font color=red> 当浏览器对某个资源的申请没有命中强缓存,就会发一个申请到服务器,验证协商缓存是否命中 </font>,如果协商缓存命中,申请响应返回的 http 状态为 304,并且会显示一个 Not Modified 的字符串示意资源未被批改
  • modified: 是批改的意思

Last-Modified 和 If-Modified-Since

  • Last-Modified 和 If-Modified-Since 都是依据 <font color=red> 服务器工夫 </font> 返回的 header
  • 响应头:Last-Modified
  • 申请头:If-Modified-Since
  • 原理

    Last-Modified If-None-Match
  • 浏览器第一次跟服务器申请一个资源,服务器在返回这个资源的同时,在 response 的 header 加上 Last-Modified 的 header

    • 这个 header 示意这个资源在服务器上的最初批改工夫
  • 浏览器再次跟服务器申请这个资源时,在 request 的 header 上加上 If-Modified-Since 的 header

    • 这个 header 的值就是上一次申请时返回的 Last-Modified 的值
  • 服务器再次收到资源申请时,依据浏览器传过来 If-Modified-Since 和资源在服务器上的最初批改工夫判断资源是否有变动

    • 如果没有变动则返回 304 Not Modified,然而不会返回资源内容;
    • 如果有变动,就失常返回资源内容。
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      // 当服务器返回 304 Not Modified 的响应时,response header 中不会再增加 Last-Modified 的 header
      // 因为既然资源没有变动,那么 Last-Modified 也就不会扭转
  • 浏览器收到 304 的响应后,就会从缓存中加载资源
  • 如果协商缓存没有命中,浏览器间接从服务器加载资源时,Last-Modified Header 在从新加载的时候会被更新

    • 下次申请时,If-Modified-Since 会启用上次返回的 Last-Modified 值

ETag 和 If-None-Match

  • <font color=red> 只有资源有变动 ETag 这个字符串就不一样,和批改工夫没有关系,所以很好的补充了 Last-Modified 的问题 </font>
  • 响应头:ETag
  • 申请头:If-None-Match
  • 原理

    ETag 和 If-None-Match
  • 浏览器第一次跟服务器申请一个资源,服务器在返回这个资源的同时,在 response 的 header 加上 ETag 的 header

    • 这个 header 是服务器依据以后申请的资源生成的一个惟一标识,这个惟一标识是一个字符串
    • 只有资源有变动这个串就不同,跟最初批改工夫没有关系,所以能很好的补充 Last-Modified 的问题
  • 浏览器再次跟服务器申请这个资源时,在 request 的 header 上加上 If-None-Match 的 header,

    • 这个 header 的值就是上一次申请时返回的 ETag 的值
  • 服务器再次收到资源申请时,依据浏览器传过来 If-None-Match 而后再依据资源生成一个新的 ETag

    • 如果没有变动则返回 304 Not Modified,然而不会返回资源内容
    • 如果有变动,就失常返回资源内容。
      // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      // 与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时
      // 因为 ETag 从新生成过,response header 中还会把这个 ETag 返回,即便这个 ETag 跟之前的没有变动
  • 浏览器收到 304 的响应后,就会从缓存中加载资源。

Last-Modified(If-Modified-Since)和 ETag(If-None-Match)的区别

  • ETag 的劣势

    • ETag 和 Last-Modified 十分类似,都是用来判断一个参数,从而决定是否启用缓存。
    • 然而 ETag 绝对于 Last-Modified 也有其劣势,能够更加精确的判断文件内容是否被批改,从而在实际操作中实用水平也更高。

强缓存和协商缓存的区别

  • 协商缓存跟强缓存不一样,强缓存不发申请到服务器,所以有时候资源更新了浏览器还不晓得,然而协商缓存会发申请到服务器,所以资源是否更新,服务器必定晓得。
  • 大部分 web 服务器都默认开启协商缓存,而且是同时启用 Last-Modified,If-Modified-Since 和 ETag、If-None-Match
  • Last-Modified,If-Modified-Since 和 ETag、If-None-Match 个别都是同时启用,这是为了解决 Last-Modified 不牢靠的状况
  • // 分布式系统里多台机器间文件的 Last-Modified 必须保持一致,免得负载平衡到不同机器导致比对失败
  • // 分布式系统尽量敞开掉 ETag(每台机器生成的 ETag 都会不一样)

浏览器缓存判断的流程

  1. 第一次失常申请后,缓存了资源和所有 header 的前提下
  2. 在资源缓存后,在缓存过期生效之前,如果再次申请该资源,<font color=red> 默认先查看强缓存 </font>

    • 强缓存命中,则间接读取
    • 未命中强缓存,则发送申请到服务器,<font color=red> 再查看是否命中协商缓存 </font>
  3. 未命中强缓存,再发申请到服务器查看是否命中协商缓存

    • 协商缓存命中,则通知浏览器还是能够从缓存读取
    • 未命中协商缓存,才从服务器返回最新的资源

https://juejin.im/post/684490…

正文完
 0