前端那些事

vuePress-theme-reco chenpeng    2020 - 2021
前端那些事 前端那些事

Choose mode

  • dark
  • auto
  • light
首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
author-avatar

chenpeng

85

Article

25

Tag

首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
  • Browser

    • 浏览器从输入URL到页面渲染的整个流程
    • 浏览器的重绘与回流
    • 浏览器跨域
    • 浏览器缓存
    • 前端安全
    • localStorage、sessionStorage、cookie、session区别

浏览器缓存

vuePress-theme-reco chenpeng    2020 - 2021

浏览器缓存

chenpeng 2020-11-30 浏览器缓存

# 1.浏览器缓存过程

  1. 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
  2. 浏览器每次拿到返回的请求结果,都会将结果和缓存标识存入浏览器缓存中

# 2.浏览器缓存机制

缓存分为强缓存和协商缓存

强缓存优先于协商缓存进行,若强缓存生效则直接使用缓存,若不生效则使用协商缓存

协商缓存由服务器决定是否使用缓存,若协商缓存生效,则返回304,直接使用缓存;若协商缓存失效,则返回200和新的资源及缓存标识,并且存入浏览器中

如果强缓存和协商缓存都没有设置,那么浏览器会采用启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 的值的 10% 作为缓存时间

# 3.强缓存

强缓存:不会向服务器发送请求,直接从缓存中读取资源,返回 200。强缓存可以通过设置两种 HTTP 请求头实现:Expires 和 Cache-Control

  1. Expires

    Expires 是 HTTP/1.0 中控制网页缓存的字段,其值为服务器返回该请求的结果缓存的到期时间,即再次发送请求时,如果客户端的时间小于 Expires 的值时,直接使用缓存的结果。Expires 的值是一个绝对时间,一般对应服务端时间,如果客户端与服务端的时间由于某些原因发生误差,那么强缓存将直接失效

  2. Cache-Control

    Cache-Control 是 HTTP/1.1 中控制网页缓存的字段,主要取值为

    • public:所有内容都将被缓存(客户端和代理服务器都可缓存)
    • private:所有内容只有客户端可以缓存
    • no-cache:客户端缓存内容,是否使用缓存则需要经过协商缓存来验证决定
    • no-store:所有内容都不会被缓存,既不使用强缓存,也不使用协商缓存
    • max-age:max-age=xxx (xxx is numeric)表示缓存内容将在xxx秒后失效
    • s-maxage(单位为s):同max-age作用一样,只在代理服务器中生效(比如CDN缓存)。比如当s-maxage=60时,在这60秒中,即使更新了CDN的内容,浏览器也不会进行请求。max-age用于普通缓存,而s-maxage用于代理缓存。s-maxage的优先级高于max-age。如果存在s-maxage,则会覆盖掉max-age和Expires header
    • max-stale:能容忍的最大过期时间,在该时间内,即使缓存过期,也使用该缓存
    • min-fresh:能容忍的最小新鲜度
  3. Expires 和 Cache-Control 对比

    Expires 是 HTTP/1.0 的产物,Cache-Control 是 HTTP/1.1 的产物,两者同时存在时,Cache-Control 的优先级高于 Expires

# 4.协商缓存

协商缓存是在强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:

  • 协商缓存生效,返回 304 和 Not Modified
  • 协商缓存失效,返回 200 和响应结果

协商缓存可以通过设置两种 HTTP header 实现:Last-Modified 和 ETag

  1. Last-Modified 和 If-Modified-Since

    浏览器在第一次访问资源时,服务器返回资源的同时,在响应头上添加 Last-Modified 的 header,值就是这个资源在服务器上的最后修改时间,浏览器接收后缓存结果和 header。

    浏览器下一次请求该资源时,浏览器检测到有 Last-Modified 这个 header,于是添加 If-Modified-Since 这个请求头,值就是 Last-Modified 的值,服务器再次接收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回 304 和空的响应体,浏览器直接从缓存中读取结果;如果 If-Modified-Since 的值小于服务器中这个资源的最后修改时间,则说明资源有更新,返回 200 和更新后的资源(包括新的 Last-Modified)

    存在的弊端:

    • 如果本地打开缓存文件,即使没有对文件进行修改,还是会造成 Last-Modified 的变化,服务端不能命中缓存导致发送相同的资源
    • 因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改了资源,那么服务端会认为资源还是命中了,不会返回更新后的资源
  2. ETag 和 If-None-Match

    ETag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,ETag 就会重新生成。浏览器再下一次请求资源时,会将上一次返回的 ETag 的值放到请求头里的 If-None-Match 里,服务器只需要比较客户端传来的 If-None-Match 跟服务器上该资源的 ETag 的值是否一致,如果一致,返回 304 和空的响应体,浏览器直接从缓存中读取结果;如果不一致,则返回 200 和更新后的资源(包括新的 ETag)

  3. Last-Modified 和 ETag 对比

    • 精度上,ETag 要优于 Last-Modified。Last-Modified 的时间单位是秒,如果某个文件在一秒内修改了多次,那么该文件的 Last-Modified 并没有体现出修改,而 ETag 使用文件的唯一标识确保了精度;如果是负载均衡的服务器,各个服务器生成的 Last-Modified 的值也可能不一样
    • 性能上,Last-Modified 要优于 ETag
    • 优先级上,服务器优先考虑 ETag