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

前言

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

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

  • 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 分钟前
前端vue-实现富文本组件
前端·vue.js·富文本
小白小白从不日白11 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风23 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
diygwcom35 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
Hello-Mr.Wang1 小时前
vue3中开发引导页的方法
开发语言·前端·javascript
WG_171 小时前
C++多态
开发语言·c++·面试
鱼跃鹰飞1 小时前
Leetcode面试经典150题-130.被围绕的区域
java·算法·leetcode·面试·职场和发展·深度优先
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七5 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦7 小时前
JavaScript substring() 方法
前端