JS 浏览器缓存

  • 缓存优点
  • 根据缓存位置区分的四种缓存
  • 缓存过程分析
  • 缓存策略
  • 缓存机制
  • 实际应用场景
  • 用户行为对浏览器缓存的影响

浏览器缓存

优点

  • 缩短网页请求资源的距离,减少延迟
  • 减少带宽,降低网络负荷
流程
  • 对于一个数据请求来说,可以分为发起网络请求,后端处理数据,浏览器响应三个步骤。浏览器缓存可以帮助我们在第一、三步中优化性能,如果浏览器中有缓存就不发起请求,发起了请求如果后端数据和前端缓存数据一致也没有必要将数据传回来,这样就减少了响应数据

缓存位置

  • 从缓存位置上来说分为四种,根据优先级为 Service Worker、Memory Cache、Disk Cache、Push Cach,当依次查找缓存且都没有命中的时候,才会去请求网络
Service Worker
  • Service Worker 是运行在浏览器背后的独立线程,一般用来实现缓存功能
    • 因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 传输协议来保障安全
    • 它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的
  • Service Worker 实现缓存功能的三个步骤:
    • 首先需要注册 Service Worker
    • 然后监听 install 事件后就可以缓存需要的文件
    • 最后在下次用户访问的时候,通过拦截请求的方式查询是否存在缓存,如果存在就直接读取缓存文件否则就去请求数据
  • 当 Service Worker 没有命中缓存的时候,我们需要去调用 fetch 函数获取数据。也就是说,如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker 中获取的内容。
Memory Cache
  • 内存中的缓存:读取高效、持续时效短,会随着进程的释放而释放
  • 在缓存资源时并不关心返回资源的请求头 Cache-Control 的值是什么,同时资源的匹配也并非仅仅是对 URL 做判断,还可能会对 Content-Type、Cors 等其他特征做校验
  • 普通刷新 F5 操作,优先使用 Memory Cache
Disk Cache
  • 硬盘中的缓存:对比 Memory Cache 读取速度慢,但是容量大、缓存时效长
  • 它根据 HTTP Header 中的字段判断哪些资源需要被缓存、哪些资源可以不请求直接使用、哪些资源已经过期需要重新请求。即使在跨站点的情况下相同地址的资源一旦被硬盘缓存下来就不会再次去请求数据
  • 对于大文件来说大概率在硬盘中缓存,反之内存缓存优先;当前系统内存使用率高的情况下文件优先存储进硬盘
Push Cach
  • HTTP/2 中的内容,时效短只在会话 Session 中存在,一旦会话结束就会被释放

缓存过程分析

  • 浏览器如何确定资源该不该缓存以及如何缓存?浏览器对缓存的处理是根据第一次请求资源时返回的响应头来确定的
  • 浏览器每次发起请求都会先在浏览器缓存中查找该请求的结果以及缓存标识
  • 浏览器每次拿到请求的结果都会将该结果和缓存标识存入浏览器缓存中

优点

  • 减少重复数据请求,避免通过网络再次加载资源,节省流量。
  • 降低服务器的压力,提升网站性能。
  • 加快客户端加载网页的速度, 提升用户体验。

缓存策略

  • 根据是否需要向服务器重新发起 HTTP 请求将缓存过程分为两个部分:强缓存和协商缓存
强缓存
  • 不会向服务器发送请求,直接从缓存中读取资源,可以设置两种 HTTP Header 来实现:Expires、Cache-Control
Expires
  • 缓存过期时间用来指定资源的过期时间,是服务器端的具体的时间点,结合 last-modified 来使用
  • 是 HTTP/1 的产物,受限于本地时间,如果本地时间修改可能会造成缓存失效
Cache-Control
  • 可以在请求头或响应头中来设置,多个指令配合使用达到多个目的
  • 是 HTTP/1.1 的产物,如果和 Expires同时存在,那么它的优先级要高,所以 Expires 的存在成为了一种兼容性的写法
协商缓存
  • 强缓存的依据来自于缓存是否过期,而不关心服务端文件是否已经更新,这可能会导致加载的文件不是服务端最新的内容,此时我们就需要用到协商缓存
  • 协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发送请求,由服务器根据缓存标识决定是否使用缓存的过程,主要分两种情况
    • 协商缓存生效返回 304 和 Not Modified
    • 协商缓存失效返回 200 和请求的结果
  • 协商缓存可以通过设置两种 HTTP Header 来实现:Last-Modified 和 ETag
Last-Modified
  • 浏览器在第一次返回资源时,在响应头中添加 Last-Modified 的 header,值是这个资源在服务器上的最后的修改时间浏览器接收后缓存文件和 header
  • 浏览器下一次请求这个资源,浏览器检测到有 Last-Modified 这个 header,于是添加 If-Modified-Since 这个 header,值就是 Last-Modified 中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回 304 和空的响应体,直接从缓存读取,如果 If-Modified-Since 的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和 200
  • Last-Modified 的弊端:
    • 如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源
    • 因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源
  • 既然根据文件修改时间来决定是否缓存尚有不足,能否可以直接根据文件内容是否修改来决定缓存策略?所以在 HTTP / 1.1 出现了 ETag 和If-None-Match
ETag
  • ETag 是服务器响应请求时,返回当前资源文件的一个唯一标识,只要资源有变化 ETag 就会重新生成
  • 浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的 Etag 值放到 request header 里的 If-None-Match 里,服务器只需要比较客户端传来的 If-None-Match 跟自己服务器上该资源的 ETag 是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现 ETag 匹配不上,那么直接以常规 GET 200 回包形式将新的资源(当然也包括了新的 ETag)发给客户端;如果 ETag 是一致的,则直接返回 304 知会客户端直接使用本地缓存即可。
  • Last-Modified 和 ETag 的区别:
    • 精度上 ETag 优于 Last-Modified
    • 性能上 ETag 逊于 Last-Modified
    • 优先级上服务器优先考虑 ETag

缓存机制

  • 强制缓存优先于协商缓存进行,若强制缓存生效则直接使用缓存,若不生效则进行协商缓存,协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回 200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回 304,继续使用缓存。
  • 如果什么缓存策略都没设置,那么浏览器会怎么处理?对于这种情况,浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。
  • 浏览器缓存分为强缓存和协商缓存,两者有两个比较明显的区别:
    • 如果浏览器命中强缓存,则不需要给服务器发请求;而协商缓存最终由服务器来决定是否使用缓存,即客户端与服务器之间存在一次通信。
      在 chrome 中强缓存(虽然没有发出真实的 http 请求)的请求状态码返回是 200 (from cache);
    • 而协商缓存如果命中走缓存的话,请求的状态码是 304 (not modified)。 不同浏览器的策略不同,在 Fire Fox中,from cache 状态码是 304.

实际应用场景

  • 频繁变动的资源:Cache-Control: no-cache
  • 不常变化的资源:Cache-Control: max-age=31536000,一年的有效期,比如 jQuery 类库基本不换化

用户行为对浏览器缓存的影响

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容