详解、带你搞懂:前端缓存,web开发工程师培训

62 阅读9分钟

最后

本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等

前端视频资料: 开源分享:docs.qq.com/doc/DSmRnRG…

在这里插入图片描述

缓存分类

===================================================================

分类一


  • HTTP缓存

  • 浏览器缓存

其中 HTTP 缓存是在 HTTP 请求传输时用到的缓存,主要在服务器代码上设置;而浏览器缓存则主要由前端开发在前端 js 上进行设置。

浏览器与服务器通信的方式为应答模式,即是:浏览器发起 HTTP 请求 – 服务器响应该请求。那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中 HTTP 头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。

分类二


  • 强制缓存

  • 协商缓存(也叫对比缓存)

强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果,强制缓存的情况主要有三种。

① 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致)

② 存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存

③ 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果

那么强制缓存的缓存规则是什么?

当浏览器向服务器发起请求时,服务器会将缓存规则放入 HTTP 响应报文的 HTTP 头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是 ExpiresCache-Control,其中 Cache-Control 优先级比 Expires 高。

Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。

到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义。

Cache-Control 的取值


在HTTP/1.1中,Cache-Control 是最重要的规则,主要用于控制网页缓存,主要取值为:

  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)

  • private:所有内容只有客户端可以缓存,Cache-Control的默认取值

  • no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

  • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

  • max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

那缓存存到哪里了呢?

  • disk cache(硬盘中的缓存)

  • memory cache(内存中的缓存)

浏览器读取缓存的顺序为 memory –> disk –> 服务器请求

在缓存领域,还有一个是 service workerservice worker 是在你手动设置了要缓存哪些文件时才会生效,而且可以离线使用缓存的文件,很厉害的,但是这里我们不做过多讲解。

内存缓存具有两个特点,分别是速度快和时间限制。

硬盘缓存读取速度比内存缓存要慢一些。

那这里就有一个疑问:强制缓存,什么时候存到 memory cache , 什么时候存在 disk cache;存储位置的规则是什么?

几乎所有的网络请求资源都会被浏览器自动加入到 memory cache 中。但是也正因为数量很大但是浏览器占用的内存不能无限扩大这样两个因素,memory cache 注定只能是个“短期存储”。常规情况下,浏览器的 TAB 关闭后该次浏览的 memory cache 便告失效 (为了给其他 TAB 腾出位置)。而如果极端情况下 (例如一个页面的缓存就占用了超级多的内存),那可能在 TAB 没关闭之前,排在前面的缓存就已经失效了。

但如果你真的不想让一个资源进入缓存,就连短期也不行,那就需要使用 no-store。存在这个头部配置的话,即便是 memory cache 也不会存储,自然也不会从中读取了。

disk cache 会严格根据 HTTP 头信息中的各类字段来判定哪些资源可以缓存,哪些资源不可以缓存;哪些资源是仍然可用的,哪些资源是过时需要重新请求的。当命中缓存之后,浏览器会从硬盘中读取资源,虽然比起从内存中读取慢了一些,但比起网络请求还是快了不少的。绝大部分的缓存都来自 disk cache

那协商缓存的缓存规则是什么?

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

① 协商缓存生效,请求返回状态为304,不返回请求结果

② 协商缓存失效,请求返回状态为200和请求结果

协商缓存的标识也是在响应报文的 HTTP 头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别有

Last-Modified / If-Modified-SinceEtag / If-None-Match

其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高。

Last-Modified / If-Modified-Since

Last-Modified 是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。

If-Modified-Since 则是客户端再次发起该请求时,携带上次请求返回的 Last-Modified 值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有 If-Modified-Since 字段,则会根据 If-Modified-Since 的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于 If-Modified-Since 的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。

Etag / If-None-Match

Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

If-None-Match 是客户端再次发起该请求时,携带上次请求返回的唯一标识 Etag 值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有 If-None-Match,则会根据 If-None-Match 的字段值与该资源在服务器的 Etag 值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。

Etag / If-None-Match 优先级高于Last-Modified / If-Modified-Since,同时存在则只有 Etag / If-None-Match 生效。对于协商缓存,使用 Ctrl+F5 强制刷新可以使得缓存无效。但是对于强缓存,在未过期时,必须更新资源路径才能发起新的请求(更改了路径相当于是另一个资源了,这也是前端工程化中常用到的技巧)

总结

=================================================================

强制缓存优先于协商缓存进行,若强制缓存(ExpiresCache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-SinceEtag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回 304,继续使用缓存。


扩展学习

===================================================================

本地存储小容量


总结

=============================================================

从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

第二阶段:移动端开发技术

第三阶段:前端常用框架

  • 推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。

  • 大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。