前端缓存相关
谈到前端性能优化,缓存策略是必聊得。今天咱们就来扒一扒主要的两部分:强缓存和协商缓存。
以前我的理解就是:当我们需要向服务器请求资源时,浏览器首先会检查,是否命中强缓存。如果命中,则直接从缓存中拿资源,注意,此情况不需要像后端发送请求。如果没有命中,就会像后端真实发送请求,然后由后端判断,是否命中协商缓存。若命中,返回304,告诉前端资源未更新,可以用本地的,若没有命中,则找到对应资源返回,状态码通常200。上面的表述不能说不对,但是显然缺少细节。现在既然要来扒一扒,咱么就深入一下。
1. 强缓存:强缓存主要是通过http请求头中的Cache-Control和Expire两个字段控制。Expire是HTTP1.0标准下的字段,在这里我们可以忽略。我们重点来讨论的Cache-Control这个字段。Cache-Control是HTTP/1.1标准下的。 一般,我们会设置Cache-Control的值为“public, max-age=xxx”,表示在xxx秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求。
为什么指定缓存过期时间需要两个字段呢?
因为有的浏览器只认识 Cache-Control,有的浏览器不认识,不认识的情况下浏览器会去找 Expires字段作为判断依据。即:Cache-Control优先级高于expires,但同时,expires兼容Cache-Control。expires字段通常是一个时间,但工作中发现,他的值有时候会被设置成session,意思就是,跟sessionstorage同样的生命周期。
2. 协商缓存:
协商缓存涉及到两个字段:Etag和last-modified。Etag表示资源唯一标识符,是根据文件内容生成的。浏览器第一次请求资源时,服务器会返回Etag、last-modified、Expires 和 Cache-Control。浏览器分别将前两者的值给到if-none-match、if-modified-since。就是说,if-none-match和Etag本质上就是一个东西,if-modified-since和last-modified也是一样。浏览器在每次请求时都会带上这俩字段用于服务器端判断是否返回资源。
从源码角度看,如果不是强制刷新,而且请求头带上了if-modified-since和if-none-match两个字段,则先判断etag,再判断last-modified。
服务端判断逻辑:last-modified和if-modified-since都表示时间。服务器收到请求后,从请求头中取出if-modified-since和资源当前的last-modified字段进行比较。如果是一样的,就说明文件没有被更新过,就返回状态码304和空响应体给浏览器,浏览器直接拿过期了的资源继续使用即可;如果对比不一样说明资源有更新,就返回状态码200和新的资源。
3. 本地存储那些事儿
前端的本地存储目前有三种方法,cookie、localstorage、sessionstorage,那么这三者之间的区别或者说,差异都有哪些呢?
后两者是h5提出的用于本地存储新的api,而cookie是h5之前大家使用的方法。
什么是token?
token实质上是一段字符串。当用户输入账户名和密码,服务器收到后用只有自己知道的加密算法,对用户信息加密,其中包括userid,加密后的产物,就是token,把token返回给前端,前端收到后,会把这个字符串存入cookie中。之后的每次请求中,都会连带这段字符串发给服务器。服务器每收到一个请求,都会取出token做一个解密判断该用户是不是自己人,然后dadadadda。。。。。
从上面这个过程能够看出,服务器实质上是通过计算耗时换取存储空间。因为一般的思路是:用户注册提交数据,服务端存储用户信息,然后每次用户登录,服务器都会去服务器中查找。一两个用户还好,10亿用户咋办?我光存储10亿的用户的信息,就得要多少空间?。。。。。利用token的那种方式,压力瞬间成了空气。什么存储数据查找数据统统不需要,唯一要做的,加密解密,花点算力而已。
token持久化
所谓持久化,就是防止用户刷新存储在redux中的token丢失。
解决方案: redux中存一份,localstorage中也存储一份
