搞定浏览器缓存,解决前端面试

前言

缓存就是首次请求之后保存一份请求资源的响应副本,当用户再次发送请求的时候,如果能命中就拦截请求,将之前存储的响应副本返回给用户,这样就避免了重新向服务器请求资源。

这篇文章主要是介绍浏览器缓存的三个方面:

  • HTTP缓存
  • Service Worker缓存
  • Push缓存

HTTP缓存

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

强缓存

概念:浏览器判断所请求的目标资源命中之后,可以直接从强缓存中返回响应,不需要经过服务器。

响应头的一些信息

与强缓存相关的响应头有:expires和cache-control。

expires:是HTTP1.0协议中声明用来控制缓存失效日期的时间戳,是由服务器端指定后通过响应头告知浏览器的,浏览器接受该字段响应体后进行缓存。之后如果再次发送相同的请求,如果expires和本地的时间戳对比,本地的时间戳小于expires那么就没有失效,可以从缓存中直接获取返回的内容。

但expires有着局限性。

expires对时间戳有着很强的依赖,客户端的本地时间戳与服务端的时间戳不同步,或者对客户端的本地时间进行修改的话,那么这个缓存失效的时间可能会与预期的不符。所以出现了cache-control

cache-control:设置max-age,这个是以秒作为单位的。例如:max-age=3153600,请求资源后的3153600秒内有效,解决了服务器端和客户端本地时间戳不同步的问题。

cache-control还有其他属性

no-cache和no-store

no-cache:开启协商缓存

no-store:不开启缓存

private和public

明确响应资源是否可被代理服务器进行缓存。

private:不能被代理服务器缓存

public:能被代理服务器缓存

max-age

告诉客户端响应资源的过期时长。

memory cache 与 disk cache 的区别?

都是强缓存,memory cache的缓存来自内存,disk cache缓存来自硬盘上。

  • memory cache:当前tab页关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,原来的 memory cache 会变成 disk cache
  • disk cache:关闭tab页甚至关闭浏览器后,数据依然存在,下次打开仍然会是 from disk cache

其中一些体积不大的js文件,css样式表会放在memory cache,体积较大的放在disk cache。

协商缓存

概念:在使用本地缓存之前,需要向服务端发一次GET请求,与之协商当前浏览器所保存到本地缓存是否过期了。

协商缓存的标识

last-modified

文件最近一次修改的时间戳。

例如:客户端需要向服务器请求一个abc.js文件,使用的是协商缓存,那么首次返回该资源的响应头就包含 last-modified字段,该字段属性值为JavaScript文件最近一次修改的时间戳,此时请求该文件的时候会包含一个if-modified-since字段,这个值为last-modified,接着服务器会将两者进行对比,如果相同的话就可以走缓存,不相同服务器端还需要重新请求全新的文件资源。

last-modified的不足.

  1. 当文件资源发生了改变,但是文件内容没有发生改变,时间戳还会进行修改,服务端就会重新请求全新资源,会造成网络带宽资源的浪费
  2. 该时间戳单位为秒,当文件修改速度很快,无法识别该文件资源的更新

所以引出了ETag。

ETag

服务器端根据不同的资源生成的一个字符串,类似文件指纹,只要文件内容发生了改变,ETag标签就会不同。

ETag的优先级比last-modified高。

首次请求的响应头

less 复制代码
Content-Type:image/jpeg
ETag:"c39046a19cd8354384c2de0c32ce7ca5"
Last-Modified:Fri,12 Jul 2019 06:45:17 GMT
Content-Length:9887

再次发起请求,会将之前响应头中ETag的字段值作为此次请求头中If-None-Match字段,提供给服务器进行缓存有效性检验。

less 复制代码
If-None-Match:"c39046a19cd8354384c2de0c32ce7ca5"
If-Modified:Fri,12 Jul 2019 06:45:17 GMT

//再次响应
Content-Type:image/jpeg
ETag:"c39046a19cd8354384c2de0c32ce7ca5"
Last-Modified:Fri,12 Jul 2019 06:45:17 GMT
Content-Length:0

如果验证缓存有效的话就返回304重定向到本地缓存。

缺点
  1. 服务器对生成文件资源的ETag需要付出额外的计算开销,如果资源过大的话,会影响服务器性能

缓存决策

缓存方案

  • HTML使用协商缓存
  • JS,图片,css使用强缓存

这样就可以解决在客户端可以实时地获取最新的内容,固定的资源会在客户端进行尽可能久的保存。

Service Worker

Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。

  1. 必须是 HTTPS。因为它涉及请求拦截,所以必须使用 HTTPS 协议来保障安全。
  2. Service Worker 缓存不同于其他机制,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。

Push缓存

Push Cache(推送缓存) 是 HTTP/2 中的内容,是基于HTTP2的连接的,当连接断开的时候,就会丢失资源,所以它适合资源推送到页面间隔较短的使用场景。

缓存优先级:当以上 3 种缓存都没有命中的时候,它才会被使用。

应用场景

  • 有效利用服务器的空闲时间进行资源推送
  • 推送HTML中的内联资源,例如js脚本,小图标,样式表

总结

  1. 缓存优先级
相关推荐
kyriewen11 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
IT_陈寒11 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
小林攻城狮12 小时前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦12 小时前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer12 小时前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队12 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY12 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
她的男孩12 小时前
后台接口加密别只会 HTTPS,ForgeAdmin 的 RSA + SM4/AES 源码拆解
后端·面试·开源
远航_12 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏13 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端