废话不多说,先上一张结构图:
前端所涉及到的缓存技术主要就是图中所示,是不是很清晰很简单?其中,关于本地存储(LocalStorage、SessionStorage)是在具体的业务逻辑中使用的。本文主要介绍前端工程体系下的缓存配置策略(也就是浏览器对于JS、css、图片等静态资源的缓存策略)
HTTP缓存策略
浏览器对静态资源的缓存本质上是HTTP协议的缓存策略,根据是否要向服务端发送请求的不同,HTTP缓存策略又可分为强制缓存和协商缓存策略。
1、强制缓存策略
浏览器不发请求,根据过期时间决定使用本地缓存还是请求新资源,这样的策略就叫做强制缓存策略。
Expires和Cache-control是强制缓存策略的重要响应头信息。
(1)Expires
Expires是HTTP1.0加入的特性,通过指定一个明确的时间点作为缓存资源的过期时间,也就是说在这个时间点之前如果再次请求此资源的话,浏览器会直接去缓存里面取,不会再发出请求。例如:(来自掘金网站analytics.js的请求)
expires: Wed, 19 Sep 2018 10:36:19 GMT
复制代码
但是Expires有个很严重的问题:它是以服务器时间来定的,但是浏览器进行过期判断是将本地的时间与它作对比,这样就会存在误差(例如服务器在中国,你在美国用浏览器访问),这显然是不合理的。
(2)Cache-control
为了解决Expires的问题,HTTP1.1新增了一个响应头信息:Cache-control。常用的Cache-control有以下几种:
no-cache:指定浏览器向服务端发出请求,经服务端确认资源是否发生变化,如果未发生变化就可以使用浏览器缓存(即协商缓存策略),如果发生变化则重新下载新资源。
no-store:指定浏览器向服务端发出请求,无论资源是否发生变化,都会重新下载资源。是真正意义上的禁止缓存。
max-age:指定从请求的时刻算起,此资源能够被缓存的最长时间,单位是秒。例如analytics.js的请求max-age=7200
,表示浏览器在2小时内如果再次遇到对于此资源的请求,会使用本地的缓存。
max-age指定的是一个时间段,相当于是绝对值,所以不受浏览器和服务器之间时间的影响。它比Expires具有更高的优先级。
2、协商缓存策略
浏览器会发出新请求,经过服务器对资源的对比后决定采用本地缓存还是新资源,这样的策略叫做协商缓存策略。(顾名思义,就是浏览器和服务器协商来解决这件事)
判断启用协商缓存策略的标准是:Cache-control设置为no-cache或者max-age与Expires都过期的情况下。
Etag和If-none-match
Etag是服务器为资源分配的唯一性标识,作为响应头信息返回给浏览器。当采用协商缓存策略时,浏览器会将Etag值通过If-none-match作为请求头发送给服务器,服务器收到请求后,会对比所请求资源的Etag值是否改变,如果未改变将会返回304 Not Modified,告诉浏览器这个文件没有任何变化,那么浏览器就回去缓存中取;如果资源发生了改变,服务器就会返回最新的资源并且重置资源的Etag值。
最后献上一张前端缓存策略流程图:(画了挺久的,画完也比较满意啊哈哈哈~!)
PS:当浏览器取本地缓存的时候,在Network里面size一栏我们可能会看到2种描述:from memory cache和from disk cache。
from memory cache:从内存中取,关闭浏览器就没了。一般脚本文件、字体、图片会存在内存当中。
from disk cache:从磁盘中取,关闭浏览器再打开该请求依然还能在磁盘中取。一般非脚本文件会存在内存当中,如css等