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

前言

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

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

  • 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. 缓存优先级
相关推荐
加班是不可能的,除非双倍日工资2 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip2 小时前
vite和webpack打包结构控制
前端·javascript
excel3 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼3 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT3 小时前
promise & async await总结
前端
Jerry说前后端3 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天4 小时前
A12预装app
linux·服务器·前端